From 63b8aaa49509ef54628061db640bc0afdf0b5a1a Mon Sep 17 00:00:00 2001 From: Moonchild Date: Mon, 29 Nov 2021 17:19:16 -0500 Subject: Issue #1845 - Remove Marionette files --- old-configure.in | 6 - testing/firefox-ui/.flake8 | 3 - testing/firefox-ui/harness/MANIFEST.in | 2 - .../harness/firefox_ui_harness/__init__.py | 8 - .../firefox_ui_harness/arguments/__init__.py | 6 - .../harness/firefox_ui_harness/arguments/base.py | 18 - .../harness/firefox_ui_harness/arguments/update.py | 65 - .../harness/firefox_ui_harness/cli_functional.py | 21 - .../harness/firefox_ui_harness/cli_update.py | 21 - .../harness/firefox_ui_harness/runners/__init__.py | 6 - .../harness/firefox_ui_harness/runners/base.py | 45 - .../harness/firefox_ui_harness/runners/update.py | 101 - .../harness/firefox_ui_harness/testcases.py | 420 -- testing/firefox-ui/harness/requirements.txt | 5 - testing/firefox-ui/harness/setup.py | 44 - testing/firefox-ui/mach_commands.py | 120 - testing/firefox-ui/moz.build | 11 - .../addons/extensions/restartless_addon_signed.xpi | Bin 186036 -> 0 bytes .../extensions/restartless_addon_unsigned.xpi | Bin 177535 -> 0 bytes .../resources/cookies/cookie_single.html | 16 - .../resources/images/firefox_favicon.ico | Bin 1150 -> 0 bytes .../resources/images/mozilla_favicon.ico | Bin 1406 -> 0 bytes .../firefox-ui/resources/images/mozilla_logo.jpg | Bin 3298 -> 0 bytes testing/firefox-ui/resources/layout/mozilla.html | 45 - .../resources/layout/mozilla_community.html | 57 - .../resources/layout/mozilla_contribute.html | 70 - .../resources/layout/mozilla_governance.html | 38 - .../resources/layout/mozilla_grants.html | 72 - .../resources/layout/mozilla_mission.html | 51 - .../resources/layout/mozilla_organizations.html | 39 - .../resources/layout/mozilla_projects.html | 60 - .../resources/private_browsing/about.html | 10 - .../resources/security/enable_privilege.html | 21 - testing/firefox-ui/resources/support.html | 19 - .../functional/keyboard_shortcuts/manifest.ini | 4 - .../keyboard_shortcuts/test_browser_window.py | 56 - .../tests/functional/locationbar/manifest.ini | 9 - .../locationbar/test_access_locationbar.py | 60 - .../locationbar/test_escape_autocomplete.py | 56 - .../locationbar/test_favicon_in_autocomplete.py | 62 - .../locationbar/test_suggest_bookmarks.py | 96 - testing/firefox-ui/tests/functional/manifest.ini | 5 - .../tests/functional/private_browsing/manifest.ini | 4 - .../test_about_private_browsing.py | 60 - .../tests/functional/security/manifest.ini | 22 - .../functional/security/test_dv_certificate.py | 85 - .../functional/security/test_enable_privilege.py | 17 - .../functional/security/test_ev_certificate.py | 112 - .../functional/security/test_mixed_content_page.py | 55 - .../security/test_mixed_script_content_blocking.py | 87 - .../functional/security/test_no_certificate.py | 81 - .../test_safe_browsing_initial_download.py | 84 - .../security/test_safe_browsing_notification.py | 149 - .../security/test_safe_browsing_warning_pages.py | 115 - .../security/test_security_notification.py | 62 - .../security/test_ssl_disabled_error_page.py | 60 - .../security/test_ssl_status_after_restart.py | 124 - .../test_submit_unencrypted_info_warning.py | 65 - .../functional/security/test_unknown_issuer.py | 34 - .../test_untrusted_connection_error_page.py | 35 - .../tests/functional/sessionstore/manifest.ini | 5 - .../test_restore_windows_after_restart.py | 150 - testing/firefox-ui/tests/puppeteer/manifest.ini | 24 - .../tests/puppeteer/test_about_window.py | 74 - testing/firefox-ui/tests/puppeteer/test_appinfo.py | 31 - testing/firefox-ui/tests/puppeteer/test_l10n.py | 51 - testing/firefox-ui/tests/puppeteer/test_menubar.py | 30 - .../tests/puppeteer/test_notifications.py | 82 - .../tests/puppeteer/test_page_info_window.py | 100 - testing/firefox-ui/tests/puppeteer/test_places.py | 85 - .../firefox-ui/tests/puppeteer/test_security.py | 45 - .../tests/puppeteer/test_software_update.py | 134 - testing/firefox-ui/tests/puppeteer/test_tabbar.py | 191 - .../firefox-ui/tests/puppeteer/test_toolbars.py | 283 -- .../tests/puppeteer/test_update_wizard.py | 67 - testing/firefox-ui/tests/puppeteer/test_utils.py | 48 - testing/firefox-ui/tests/puppeteer/test_windows.py | 259 - .../firefox-ui/tests/update/direct/manifest.ini | 4 - .../tests/update/direct/test_direct_update.py | 21 - .../firefox-ui/tests/update/fallback/manifest.ini | 4 - .../tests/update/fallback/test_fallback_update.py | 22 - testing/firefox-ui/tests/update/manifest.ini | 2 - testing/mach_commands.py | 22 - testing/marionette/accessibility.js | 441 -- testing/marionette/action.js | 1348 ----- testing/marionette/addon.js | 104 - testing/marionette/assert.js | 322 -- testing/marionette/atom.js | 192 - testing/marionette/browser.js | 436 -- testing/marionette/capture.js | 193 - testing/marionette/cert.js | 139 - testing/marionette/chrome/test.xul | 25 - testing/marionette/chrome/test2.xul | 19 - .../marionette/chrome/test_anonymous_content.xul | 37 - testing/marionette/chrome/test_dialog.dtd | 7 - testing/marionette/chrome/test_dialog.properties | 7 - testing/marionette/chrome/test_dialog.xul | 36 - testing/marionette/chrome/test_nested_iframe.xul | 9 - testing/marionette/client/.flake8 | 3 - testing/marionette/client/MANIFEST.in | 2 - testing/marionette/client/docs/Makefile | 153 - .../marionette/client/docs/advanced/actions.rst | 46 - testing/marionette/client/docs/advanced/debug.rst | 54 - .../client/docs/advanced/findelement.rst | 126 - .../marionette/client/docs/advanced/landing.rst | 13 - testing/marionette/client/docs/advanced/stale.rst | 71 - testing/marionette/client/docs/basics.rst | 185 - testing/marionette/client/docs/conf.py | 259 - testing/marionette/client/docs/index.rst | 16 - testing/marionette/client/docs/interactive.rst | 55 - testing/marionette/client/docs/make.bat | 190 - testing/marionette/client/docs/reference.rst | 51 - .../client/marionette_driver/__init__.py | 26 - .../marionette/client/marionette_driver/addons.py | 70 - testing/marionette/client/marionette_driver/by.py | 27 - .../client/marionette_driver/date_time_value.py | 49 - .../client/marionette_driver/decorators.py | 69 - .../marionette/client/marionette_driver/errors.py | 179 - .../client/marionette_driver/expected.py | 311 -- .../client/marionette_driver/geckoinstance.py | 464 -- .../client/marionette_driver/gestures.py | 93 - .../marionette/client/marionette_driver/keys.py | 84 - .../client/marionette_driver/localization.py | 54 - .../client/marionette_driver/marionette.py | 2153 -------- .../client/marionette_driver/selection.py | 227 - .../marionette/client/marionette_driver/timeout.py | 98 - .../client/marionette_driver/transport.py | 300 -- .../marionette/client/marionette_driver/wait.py | 167 - testing/marionette/client/requirements.txt | 2 - testing/marionette/client/setup.py | 49 - testing/marionette/components/marionette.js | 237 - testing/marionette/components/marionette.manifest | 4 - testing/marionette/components/moz.build | 9 - testing/marionette/cookies.js | 131 - testing/marionette/dispatcher.js | 228 - testing/marionette/driver.js | 2907 ----------- testing/marionette/element.js | 1171 ----- testing/marionette/error.js | 500 -- testing/marionette/evaluate.js | 494 -- testing/marionette/event.js | 1365 ----- testing/marionette/frame.js | 260 - testing/marionette/harness/.flake8 | 3 - testing/marionette/harness/MANIFEST.in | 3 - testing/marionette/harness/README.rst | 30 - .../harness/marionette_harness/__init__.py | 35 - .../marionette_harness/marionette_test/__init__.py | 31 - .../marionette_test/decorators.py | 239 - .../marionette_test/testcases.py | 504 -- .../harness/marionette_harness/runner/__init__.py | 22 - .../harness/marionette_harness/runner/base.py | 1076 ---- .../harness/marionette_harness/runner/httpd.py | 142 - .../marionette_harness/runner/mixins/__init__.py | 13 - .../runner/mixins/browsermob-proxy-py/History.md | 57 - .../browsermobproxy/__init__.py | 6 - .../browsermob-proxy-py/browsermobproxy/client.py | 326 -- .../browsermob-proxy-py/browsermobproxy/server.py | 106 - .../browsermobproxy/webdriver_event_listener.py | 34 - .../mixins/browsermob-proxy-py/docs/Makefile | 153 - .../docs/_build/html/.buildinfo | 4 - .../docs/_build/html/_modules/browsermobproxy.html | 98 - .../docs/_build/html/_modules/index.html | 90 - .../docs/_build/html/_sources/client.txt | 8 - .../docs/_build/html/_sources/index.txt | 72 - .../docs/_build/html/_sources/server.txt | 8 - .../docs/_build/html/_static/basic.css | 537 -- .../docs/_build/html/_static/default.css | 256 - .../docs/_build/html/_static/doctools.js | 238 - .../docs/_build/html/_static/jquery.js | 2 - .../docs/_build/html/_static/pygments.css | 62 - .../docs/_build/html/_static/searchtools.js | 622 --- .../docs/_build/html/_static/sidebar.js | 159 - .../docs/_build/html/_static/underscore.js | 31 - .../docs/_build/html/_static/websupport.js | 808 --- .../docs/_build/html/client.html | 404 -- .../docs/_build/html/genindex.html | 297 -- .../docs/_build/html/index.html | 174 - .../docs/_build/html/objects.inv | 6 - .../docs/_build/html/py-modindex.html | 112 - .../docs/_build/html/search.html | 105 - .../docs/_build/html/searchindex.js | 1 - .../docs/_build/html/server.html | 157 - .../mixins/browsermob-proxy-py/docs/client.rst | 8 - .../runner/mixins/browsermob-proxy-py/docs/conf.py | 243 - .../mixins/browsermob-proxy-py/docs/index.rst | 72 - .../mixins/browsermob-proxy-py/docs/make.bat | 190 - .../mixins/browsermob-proxy-py/docs/server.rst | 8 - .../runner/mixins/browsermob-proxy-py/readme.md | 88 - .../runner/mixins/browsermob-proxy-py/setup.py | 20 - .../mixins/browsermob-proxy-py/test/test_client.py | 247 - .../mixins/browsermob-proxy-py/test/test_remote.py | 31 - .../browsermob-proxy-py/test/test_webdriver.py | 60 - .../marionette_harness/runner/mixins/browsermob.py | 80 - .../runner/mixins/window_manager.py | 129 - .../harness/marionette_harness/runner/serve.py | 227 - .../harness/marionette_harness/runner/test.cert | 86 - .../harness/marionette_harness/runner/test.key | 28 - .../harness/marionette_harness/runtests.py | 98 - .../tests/harness_unit/conftest.py | 100 - .../tests/harness_unit/test_httpd.py | 90 - .../harness_unit/test_marionette_arguments.py | 32 - .../tests/harness_unit/test_marionette_harness.py | 108 - .../tests/harness_unit/test_marionette_runner.py | 442 -- .../harness_unit/test_marionette_test_result.py | 54 - .../tests/harness_unit/test_serve.py | 67 - .../marionette_harness/tests/unit-tests.ini | 11 - .../tests/unit/importanotherscript.js | 1 - .../marionette_harness/tests/unit/importscript.js | 1 - .../tests/unit/mn-restartless-unsigned.xpi | Bin 1552 -> 0 bytes .../tests/unit/single_finger_functions.py | 131 - .../tests/unit/test_about_pages.py | 134 - .../tests/unit/test_accessibility.py | 210 - .../marionette_harness/tests/unit/test_addons.py | 58 - .../tests/unit/test_anonymous_content.py | 90 - .../tests/unit/test_browsermobproxy.py | 34 - .../tests/unit/test_capabilities.py | 253 - .../marionette_harness/tests/unit/test_checkbox.py | 17 - .../tests/unit/test_checkbox_chrome.py | 36 - .../marionette_harness/tests/unit/test_chrome.py | 51 - .../tests/unit/test_chrome_async_finish.js | 6 - .../tests/unit/test_chrome_element_css.py | 23 - .../marionette_harness/tests/unit/test_clearing.py | 72 - .../marionette_harness/tests/unit/test_click.py | 271 - .../tests/unit/test_click_chrome.py | 35 - .../tests/unit/test_click_scrolling.py | 117 - .../marionette_harness/tests/unit/test_cookies.py | 115 - .../marionette_harness/tests/unit/test_crash.py | 155 - .../tests/unit/test_data_driven.py | 67 - .../tests/unit/test_date_time_value.py | 29 - .../tests/unit/test_element_retrieval.py | 483 -- .../tests/unit/test_element_state.py | 162 - .../tests/unit/test_element_state_chrome.py | 85 - .../tests/unit/test_elementsize.py | 17 - .../tests/unit/test_elementsize_chrome.py | 34 - .../marionette_harness/tests/unit/test_errors.py | 77 - .../tests/unit/test_execute_async_script.py | 156 - .../tests/unit/test_execute_isolate.py | 37 - .../tests/unit/test_execute_sandboxes.py | 79 - .../tests/unit/test_execute_script.py | 402 -- .../marionette_harness/tests/unit/test_expected.py | 228 - .../tests/unit/test_expectedfail.py | 11 - .../tests/unit/test_file_upload.py | 152 - .../tests/unit/test_findelement_chrome.py | 82 - .../tests/unit/test_geckoinstance.py | 25 - .../tests/unit/test_getactiveframe_oop.py | 93 - .../tests/unit/test_implicit_waits.py | 26 - .../tests/unit/test_import_script.py | 138 - .../tests/unit/test_key_actions.py | 91 - .../tests/unit/test_localization.py | 56 - .../marionette_harness/tests/unit/test_log.py | 64 - .../tests/unit/test_marionette.py | 67 - .../tests/unit/test_modal_dialogs.py | 198 - .../tests/unit/test_mouse_action.py | 114 - .../tests/unit/test_navigation.py | 447 -- .../tests/unit/test_pagesource.py | 33 - .../tests/unit/test_pagesource_chrome.py | 29 - .../marionette_harness/tests/unit/test_position.py | 19 - .../marionette_harness/tests/unit/test_prefs.py | 167 - .../tests/unit/test_profile_management.py | 34 - .../marionette_harness/tests/unit/test_proxy.py | 252 - .../tests/unit/test_quit_restart.py | 173 - .../tests/unit/test_rendered_element.py | 34 - .../marionette_harness/tests/unit/test_report.py | 29 - .../tests/unit/test_run_js_test.py | 10 - .../tests/unit/test_screen_orientation.py | 86 - .../tests/unit/test_screenshot.py | 428 -- .../marionette_harness/tests/unit/test_select.py | 164 - .../marionette_harness/tests/unit/test_session.py | 56 - .../tests/unit/test_set_window_size.py | 84 - .../tests/unit/test_shadow_dom.py | 80 - .../tests/unit/test_simpletest_chrome.js | 12 - .../tests/unit/test_simpletest_fail.js | 16 - .../tests/unit/test_simpletest_pass.js | 12 - .../tests/unit/test_simpletest_sanity.py | 107 - .../tests/unit/test_simpletest_timeout.js | 16 - .../tests/unit/test_single_finger_desktop.py | 123 - .../tests/unit/test_skip_setup.py | 35 - .../tests/unit/test_switch_frame.py | 183 - .../tests/unit/test_switch_frame_chrome.py | 56 - .../tests/unit/test_switch_remote_frame.py | 118 - .../tests/unit/test_switch_window_chrome.py | 124 - .../tests/unit/test_switch_window_content.py | 171 - .../tests/unit/test_teardown_context_preserved.py | 21 - .../marionette_harness/tests/unit/test_text.py | 224 - .../tests/unit/test_text_chrome.py | 44 - .../marionette_harness/tests/unit/test_timeouts.py | 115 - .../tests/unit/test_transport.py | 172 - .../marionette_harness/tests/unit/test_typing.py | 332 -- .../tests/unit/test_using_permissions.py | 46 - .../tests/unit/test_visibility.py | 121 - .../marionette_harness/tests/unit/test_wait.py | 347 -- .../tests/unit/test_window_close_chrome.py | 80 - .../tests/unit/test_window_close_content.py | 81 - .../tests/unit/test_window_handles_chrome.py | 207 - .../tests/unit/test_window_handles_content.py | 96 - .../tests/unit/test_window_position.py | 42 - .../tests/unit/test_window_title.py | 12 - .../tests/unit/test_window_title_chrome.py | 26 - .../tests/unit/test_window_type.py | 27 - .../tests/unit/test_with_using_context.py | 66 - .../marionette_harness/tests/unit/unit-tests.ini | 132 - .../marionette_harness/tests/webapi-tests.ini | 5 - .../harness/marionette_harness/www/black.png | Bin 150 -> 0 bytes .../harness/marionette_harness/www/bug814037.html | 55 - .../www/click_out_of_bounds_overflow.html | 90 - .../harness/marionette_harness/www/clicks.html | 39 - .../marionette_harness/www/cssTransform.html | 61 - .../marionette_harness/www/cssTransform2.html | 20 - .../marionette_harness/www/datetimePage.html | 15 - .../marionette_harness/www/deletingFrame.html | 29 - .../marionette_harness/www/double_click.html | 18 - .../marionette_harness/www/element_bottom.html | 12 - .../marionette_harness/www/element_left.html | 12 - .../www/element_outside_viewport.html | 41 - .../marionette_harness/www/element_right.html | 12 - .../marionette_harness/www/element_top.html | 12 - .../harness/marionette_harness/www/empty.html | 12 - .../harness/marionette_harness/www/formPage.html | 116 - .../harness/marionette_harness/www/frameset.html | 14 - .../marionette_harness/www/framesetPage2.html | 7 - .../harness/marionette_harness/www/hidden.html | 5 - .../harness/marionette_harness/www/html5/blue.jpg | Bin 92 -> 0 bytes .../www/html5/boolean_attributes.html | 2 - .../marionette_harness/www/html5/geolocation.js | 18 - .../harness/marionette_harness/www/html5/green.jpg | Bin 92 -> 0 bytes .../marionette_harness/www/html5/offline.html | 1 - .../harness/marionette_harness/www/html5/red.jpg | Bin 92 -> 0 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 92 -> 0 bytes .../harness/marionette_harness/www/html5Page.html | 45 - .../marionette_harness/www/javascriptPage.html | 278 -- .../harness/marionette_harness/www/macbeth.html | 5254 -------------------- .../marionette_harness/www/modal_dialogs.html | 39 - .../marionette_harness/www/nestedElements.html | 9 - .../harness/marionette_harness/www/rectangles.html | 40 - .../harness/marionette_harness/www/resultPage.html | 17 - .../harness/marionette_harness/www/scroll.html | 30 - .../harness/marionette_harness/www/scroll2.html | 24 - .../harness/marionette_harness/www/scroll3.html | 18 - .../harness/marionette_harness/www/scroll4.html | 15 - .../harness/marionette_harness/www/scroll5.html | 20 - .../harness/marionette_harness/www/shim.js | 282 -- .../harness/marionette_harness/www/test.html | 38 - .../harness/marionette_harness/www/testAction.html | 94 - .../marionette_harness/www/testPageSource.html | 14 - .../marionette_harness/www/testPageSource.xml | 5 - .../www/testPageSourceWithUnicodeChars.html | 11 - .../harness/marionette_harness/www/testSize.html | 9 - .../marionette_harness/www/test_accessibility.html | 57 - .../www/test_carets_columns.html | 31 - .../marionette_harness/www/test_carets_cursor.html | 31 - .../www/test_carets_display_none.html | 10 - .../marionette_harness/www/test_carets_iframe.html | 20 - .../www/test_carets_longtext.html | 9 - .../www/test_carets_multipleline.html | 24 - .../www/test_carets_multiplerange.html | 19 - .../www/test_carets_selection.html | 38 - .../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 | 15 - .../harness/marionette_harness/www/test_oop_2.html | 15 - .../marionette_harness/www/test_shadow_dom.html | 26 - .../marionette_harness/www/test_windows.html | 14 - .../harness/marionette_harness/www/white.png | Bin 150 -> 0 bytes .../marionette_harness/www/windowHandles.html | 16 - .../harness/marionette_harness/www/xhtmlTest.html | 79 - testing/marionette/harness/requirements.txt | 14 - testing/marionette/harness/setup.py | 59 - testing/marionette/interaction.js | 505 -- testing/marionette/jar.mn | 43 - testing/marionette/l10n.js | 95 - testing/marionette/legacyaction.js | 477 -- testing/marionette/listener.js | 1816 ------- testing/marionette/logging.js | 75 - testing/marionette/mach_commands.py | 81 - testing/marionette/mach_test_package_commands.py | 67 - testing/marionette/marionette.eslintrc.js | 8 - testing/marionette/message.js | 285 -- testing/marionette/modal.js | 113 - testing/marionette/moz.build | 13 - testing/marionette/navigate.js | 119 - testing/marionette/proxy.js | 376 -- testing/marionette/puppeteer/.flake8 | 3 - testing/marionette/puppeteer/firefox/MANIFEST.in | 2 - testing/marionette/puppeteer/firefox/docs/Makefile | 177 - .../puppeteer/firefox/docs/api/appinfo.rst | 15 - .../marionette/puppeteer/firefox/docs/api/keys.rst | 12 - .../marionette/puppeteer/firefox/docs/api/l10n.rst | 11 - .../puppeteer/firefox/docs/api/places.rst | 13 - .../puppeteer/firefox/docs/api/security.rst | 13 - .../puppeteer/firefox/docs/api/software_update.rst | 30 - .../puppeteer/firefox/docs/api/utils.rst | 12 - testing/marionette/puppeteer/firefox/docs/conf.py | 270 - .../marionette/puppeteer/firefox/docs/index.rst | 85 - testing/marionette/puppeteer/firefox/docs/make.bat | 242 - .../firefox/docs/ui/about_window/window.rst | 59 - .../firefox/docs/ui/browser/notifications.rst | 44 - .../puppeteer/firefox/docs/ui/browser/tabbar.rst | 22 - .../puppeteer/firefox/docs/ui/browser/toolbars.rst | 28 - .../puppeteer/firefox/docs/ui/browser/window.rst | 11 - .../marionette/puppeteer/firefox/docs/ui/deck.rst | 9 - .../marionette/puppeteer/firefox/docs/ui/menu.rst | 10 - .../puppeteer/firefox/docs/ui/pageinfo/window.rst | 30 - .../firefox/docs/ui/update_wizard/dialog.rst | 128 - .../puppeteer/firefox/docs/ui/windows.rst | 16 - .../firefox/firefox_puppeteer/__init__.py | 9 - .../firefox/firefox_puppeteer/api/__init__.py | 0 .../firefox/firefox_puppeteer/api/appinfo.py | 45 - .../firefox/firefox_puppeteer/api/keys.py | 17 - .../firefox/firefox_puppeteer/api/l10n.py | 125 - .../firefox/firefox_puppeteer/api/places.py | 150 - .../firefox/firefox_puppeteer/api/security.py | 68 - .../firefox_puppeteer/api/software_update.py | 411 -- .../firefox/firefox_puppeteer/api/utils.py | 140 - .../puppeteer/firefox/firefox_puppeteer/base.py | 14 - .../firefox/firefox_puppeteer/decorators.py | 35 - .../puppeteer/firefox/firefox_puppeteer/errors.py | 21 - .../puppeteer/firefox/firefox_puppeteer/mixins.py | 101 - .../firefox/firefox_puppeteer/puppeteer.py | 84 - .../firefox/firefox_puppeteer/ui/__init__.py | 0 .../firefox_puppeteer/ui/about_window/__init__.py | 0 .../firefox_puppeteer/ui/about_window/deck.py | 174 - .../firefox_puppeteer/ui/about_window/window.py | 32 - .../puppeteer/firefox/firefox_puppeteer/ui/base.py | 54 - .../firefox_puppeteer/ui/browser/__init__.py | 3 - .../firefox_puppeteer/ui/browser/notifications.py | 116 - .../firefox/firefox_puppeteer/ui/browser/tabbar.py | 388 -- .../firefox_puppeteer/ui/browser/toolbars.py | 641 --- .../firefox/firefox_puppeteer/ui/browser/window.py | 260 - .../puppeteer/firefox/firefox_puppeteer/ui/deck.py | 17 - .../puppeteer/firefox/firefox_puppeteer/ui/menu.py | 110 - .../firefox_puppeteer/ui/pageinfo/__init__.py | 0 .../firefox/firefox_puppeteer/ui/pageinfo/deck.py | 204 - .../firefox_puppeteer/ui/pageinfo/window.py | 61 - .../firefox_puppeteer/ui/update_wizard/__init__.py | 5 - .../firefox_puppeteer/ui/update_wizard/dialog.py | 46 - .../firefox_puppeteer/ui/update_wizard/wizard.py | 291 -- .../firefox/firefox_puppeteer/ui/windows.py | 435 -- .../puppeteer/firefox/requirements-docs.txt | 5 - .../marionette/puppeteer/firefox/requirements.txt | 2 - testing/marionette/puppeteer/firefox/setup.py | 36 - testing/marionette/server.js | 144 - testing/marionette/session.js | 457 -- testing/marionette/simpletest.js | 208 - testing/marionette/test_action.js | 627 --- testing/marionette/test_assert.js | 126 - testing/marionette/test_element.js | 55 - testing/marionette/test_error.js | 431 -- testing/marionette/test_message.js | 204 - testing/marionette/test_navigate.js | 67 - testing/marionette/test_session.js | 370 -- testing/marionette/unit.ini | 16 - 456 files changed, 60175 deletions(-) delete mode 100644 testing/firefox-ui/.flake8 delete mode 100644 testing/firefox-ui/harness/MANIFEST.in delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/__init__.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/arguments/__init__.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/arguments/base.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/arguments/update.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/cli_functional.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/cli_update.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/runners/__init__.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/runners/base.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/runners/update.py delete mode 100644 testing/firefox-ui/harness/firefox_ui_harness/testcases.py delete mode 100644 testing/firefox-ui/harness/requirements.txt delete mode 100644 testing/firefox-ui/harness/setup.py delete mode 100644 testing/firefox-ui/mach_commands.py delete mode 100644 testing/firefox-ui/moz.build delete mode 100644 testing/firefox-ui/resources/addons/extensions/restartless_addon_signed.xpi delete mode 100644 testing/firefox-ui/resources/addons/extensions/restartless_addon_unsigned.xpi delete mode 100644 testing/firefox-ui/resources/cookies/cookie_single.html delete mode 100644 testing/firefox-ui/resources/images/firefox_favicon.ico delete mode 100644 testing/firefox-ui/resources/images/mozilla_favicon.ico delete mode 100644 testing/firefox-ui/resources/images/mozilla_logo.jpg delete mode 100644 testing/firefox-ui/resources/layout/mozilla.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_community.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_contribute.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_governance.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_grants.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_mission.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_organizations.html delete mode 100644 testing/firefox-ui/resources/layout/mozilla_projects.html delete mode 100644 testing/firefox-ui/resources/private_browsing/about.html delete mode 100644 testing/firefox-ui/resources/security/enable_privilege.html delete mode 100644 testing/firefox-ui/resources/support.html delete mode 100644 testing/firefox-ui/tests/functional/keyboard_shortcuts/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py delete mode 100644 testing/firefox-ui/tests/functional/locationbar/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py delete mode 100644 testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py delete mode 100644 testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py delete mode 100644 testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py delete mode 100644 testing/firefox-ui/tests/functional/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/private_browsing/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py delete mode 100644 testing/firefox-ui/tests/functional/security/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/security/test_dv_certificate.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_enable_privilege.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_ev_certificate.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_mixed_content_page.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_no_certificate.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_security_notification.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_unknown_issuer.py delete mode 100644 testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py delete mode 100644 testing/firefox-ui/tests/functional/sessionstore/manifest.ini delete mode 100644 testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py delete mode 100644 testing/firefox-ui/tests/puppeteer/manifest.ini delete mode 100644 testing/firefox-ui/tests/puppeteer/test_about_window.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_appinfo.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_l10n.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_menubar.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_notifications.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_page_info_window.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_places.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_security.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_software_update.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_tabbar.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_toolbars.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_update_wizard.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_utils.py delete mode 100644 testing/firefox-ui/tests/puppeteer/test_windows.py delete mode 100644 testing/firefox-ui/tests/update/direct/manifest.ini delete mode 100644 testing/firefox-ui/tests/update/direct/test_direct_update.py delete mode 100644 testing/firefox-ui/tests/update/fallback/manifest.ini delete mode 100644 testing/firefox-ui/tests/update/fallback/test_fallback_update.py delete mode 100644 testing/firefox-ui/tests/update/manifest.ini delete mode 100644 testing/marionette/accessibility.js delete mode 100644 testing/marionette/action.js delete mode 100644 testing/marionette/addon.js delete mode 100644 testing/marionette/assert.js delete mode 100644 testing/marionette/atom.js delete mode 100644 testing/marionette/browser.js delete mode 100644 testing/marionette/capture.js delete mode 100644 testing/marionette/cert.js delete mode 100644 testing/marionette/chrome/test.xul delete mode 100644 testing/marionette/chrome/test2.xul delete mode 100644 testing/marionette/chrome/test_anonymous_content.xul delete mode 100644 testing/marionette/chrome/test_dialog.dtd delete mode 100644 testing/marionette/chrome/test_dialog.properties delete mode 100644 testing/marionette/chrome/test_dialog.xul delete mode 100644 testing/marionette/chrome/test_nested_iframe.xul delete mode 100644 testing/marionette/client/.flake8 delete mode 100644 testing/marionette/client/MANIFEST.in delete mode 100644 testing/marionette/client/docs/Makefile delete mode 100644 testing/marionette/client/docs/advanced/actions.rst delete mode 100644 testing/marionette/client/docs/advanced/debug.rst delete mode 100644 testing/marionette/client/docs/advanced/findelement.rst delete mode 100644 testing/marionette/client/docs/advanced/landing.rst delete mode 100644 testing/marionette/client/docs/advanced/stale.rst delete mode 100644 testing/marionette/client/docs/basics.rst delete mode 100644 testing/marionette/client/docs/conf.py delete mode 100644 testing/marionette/client/docs/index.rst delete mode 100644 testing/marionette/client/docs/interactive.rst delete mode 100644 testing/marionette/client/docs/make.bat delete mode 100644 testing/marionette/client/docs/reference.rst delete mode 100644 testing/marionette/client/marionette_driver/__init__.py delete mode 100644 testing/marionette/client/marionette_driver/addons.py delete mode 100644 testing/marionette/client/marionette_driver/by.py delete mode 100644 testing/marionette/client/marionette_driver/date_time_value.py delete mode 100644 testing/marionette/client/marionette_driver/decorators.py delete mode 100644 testing/marionette/client/marionette_driver/errors.py delete mode 100644 testing/marionette/client/marionette_driver/expected.py delete mode 100644 testing/marionette/client/marionette_driver/geckoinstance.py delete mode 100644 testing/marionette/client/marionette_driver/gestures.py delete mode 100644 testing/marionette/client/marionette_driver/keys.py delete mode 100644 testing/marionette/client/marionette_driver/localization.py delete mode 100644 testing/marionette/client/marionette_driver/marionette.py delete mode 100644 testing/marionette/client/marionette_driver/selection.py delete mode 100644 testing/marionette/client/marionette_driver/timeout.py delete mode 100644 testing/marionette/client/marionette_driver/transport.py delete mode 100644 testing/marionette/client/marionette_driver/wait.py delete mode 100644 testing/marionette/client/requirements.txt delete mode 100644 testing/marionette/client/setup.py delete mode 100644 testing/marionette/components/marionette.js delete mode 100644 testing/marionette/components/marionette.manifest delete mode 100644 testing/marionette/components/moz.build delete mode 100644 testing/marionette/cookies.js delete mode 100644 testing/marionette/dispatcher.js delete mode 100644 testing/marionette/driver.js delete mode 100644 testing/marionette/element.js delete mode 100644 testing/marionette/error.js delete mode 100644 testing/marionette/evaluate.js delete mode 100644 testing/marionette/event.js delete mode 100644 testing/marionette/frame.js delete mode 100644 testing/marionette/harness/.flake8 delete mode 100644 testing/marionette/harness/MANIFEST.in delete mode 100644 testing/marionette/harness/README.rst delete mode 100644 testing/marionette/harness/marionette_harness/__init__.py delete mode 100644 testing/marionette/harness/marionette_harness/marionette_test/__init__.py delete mode 100644 testing/marionette/harness/marionette_harness/marionette_test/decorators.py delete mode 100644 testing/marionette/harness/marionette_harness/marionette_test/testcases.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/__init__.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/base.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/httpd.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/__init__.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/History.md delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/browsermobproxy/__init__.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/browsermobproxy/client.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/browsermobproxy/server.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/browsermobproxy/webdriver_event_listener.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/Makefile delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/.buildinfo delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_modules/browsermobproxy.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_modules/index.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_sources/client.txt delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_sources/index.txt delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_sources/server.txt delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/basic.css delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/default.css delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/doctools.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/jquery.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/pygments.css delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/searchtools.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/sidebar.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/underscore.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/_static/websupport.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/client.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/genindex.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/index.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/objects.inv delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/py-modindex.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/search.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/searchindex.js delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/_build/html/server.html delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/client.rst delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/conf.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/index.rst delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/make.bat delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/docs/server.rst delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/readme.md delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/setup.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/test/test_client.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/test/test_remote.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py/test/test_webdriver.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/browsermob.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/window_manager.py delete mode 100755 testing/marionette/harness/marionette_harness/runner/serve.py delete mode 100644 testing/marionette/harness/marionette_harness/runner/test.cert delete mode 100644 testing/marionette/harness/marionette_harness/runner/test.key delete mode 100644 testing/marionette/harness/marionette_harness/runtests.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/conftest.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit-tests.ini delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/importanotherscript.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/importscript.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/mn-restartless-unsigned.xpi delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/single_finger_functions.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_addons.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_anonymous_content.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_browsermobproxy.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_checkbox.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_checkbox_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome_async_finish.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome_element_css.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_clearing.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_cookies.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_crash.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_data_driven.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_date_time_value.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_retrieval.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_state.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_elementsize.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_elementsize_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_errors.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_async_script.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_isolate.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_sandboxes.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_expected.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_expectedfail.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_file_upload.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_findelement_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_geckoinstance.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_getactiveframe_oop.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_implicit_waits.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_key_actions.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_localization.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_log.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_pagesource.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_pagesource_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_position.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_prefs.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_proxy.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_rendered_element.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_report.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_run_js_test.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_select.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_session.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_set_window_size.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_shadow_dom.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_simpletest_chrome.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_simpletest_fail.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_simpletest_pass.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_simpletest_sanity.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_simpletest_timeout.js delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_skip_setup.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_remote_frame.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_window_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_window_content.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_teardown_context_preserved.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_text.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_timeouts.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_transport.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_typing.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_using_permissions.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_visibility.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_wait.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_close_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_close_content.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_handles_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_handles_content.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_position.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_title.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_title_chrome.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_type.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_with_using_context.py delete mode 100644 testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini delete mode 100644 testing/marionette/harness/marionette_harness/tests/webapi-tests.ini delete mode 100644 testing/marionette/harness/marionette_harness/www/black.png delete mode 100644 testing/marionette/harness/marionette_harness/www/bug814037.html delete mode 100644 testing/marionette/harness/marionette_harness/www/click_out_of_bounds_overflow.html delete mode 100644 testing/marionette/harness/marionette_harness/www/clicks.html delete mode 100644 testing/marionette/harness/marionette_harness/www/cssTransform.html delete mode 100644 testing/marionette/harness/marionette_harness/www/cssTransform2.html delete mode 100644 testing/marionette/harness/marionette_harness/www/datetimePage.html delete mode 100644 testing/marionette/harness/marionette_harness/www/deletingFrame.html delete mode 100644 testing/marionette/harness/marionette_harness/www/double_click.html delete mode 100644 testing/marionette/harness/marionette_harness/www/element_bottom.html delete mode 100644 testing/marionette/harness/marionette_harness/www/element_left.html delete mode 100644 testing/marionette/harness/marionette_harness/www/element_outside_viewport.html delete mode 100644 testing/marionette/harness/marionette_harness/www/element_right.html delete mode 100644 testing/marionette/harness/marionette_harness/www/element_top.html delete mode 100644 testing/marionette/harness/marionette_harness/www/empty.html delete mode 100644 testing/marionette/harness/marionette_harness/www/formPage.html delete mode 100644 testing/marionette/harness/marionette_harness/www/frameset.html delete mode 100644 testing/marionette/harness/marionette_harness/www/framesetPage2.html delete mode 100644 testing/marionette/harness/marionette_harness/www/hidden.html delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/blue.jpg delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/geolocation.js delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/green.jpg delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/offline.html delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/red.jpg delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/status.html delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/test.appcache delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html delete mode 100644 testing/marionette/harness/marionette_harness/www/html5/yellow.jpg delete mode 100644 testing/marionette/harness/marionette_harness/www/html5Page.html delete mode 100644 testing/marionette/harness/marionette_harness/www/javascriptPage.html delete mode 100644 testing/marionette/harness/marionette_harness/www/macbeth.html delete mode 100644 testing/marionette/harness/marionette_harness/www/modal_dialogs.html delete mode 100644 testing/marionette/harness/marionette_harness/www/nestedElements.html delete mode 100644 testing/marionette/harness/marionette_harness/www/rectangles.html delete mode 100644 testing/marionette/harness/marionette_harness/www/resultPage.html delete mode 100644 testing/marionette/harness/marionette_harness/www/scroll.html delete mode 100644 testing/marionette/harness/marionette_harness/www/scroll2.html delete mode 100644 testing/marionette/harness/marionette_harness/www/scroll3.html delete mode 100644 testing/marionette/harness/marionette_harness/www/scroll4.html delete mode 100644 testing/marionette/harness/marionette_harness/www/scroll5.html delete mode 100644 testing/marionette/harness/marionette_harness/www/shim.js delete mode 100644 testing/marionette/harness/marionette_harness/www/test.html delete mode 100644 testing/marionette/harness/marionette_harness/www/testAction.html delete mode 100644 testing/marionette/harness/marionette_harness/www/testPageSource.html delete mode 100644 testing/marionette/harness/marionette_harness/www/testPageSource.xml delete mode 100644 testing/marionette/harness/marionette_harness/www/testPageSourceWithUnicodeChars.html delete mode 100644 testing/marionette/harness/marionette_harness/www/testSize.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_accessibility.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_columns.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_cursor.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_display_none.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_iframe.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_longtext.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_multipleline.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_multiplerange.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_carets_selection.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_clearing.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_dynamic.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_iframe.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_inner_iframe.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_nested_iframe.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_oop_1.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_oop_2.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_shadow_dom.html delete mode 100644 testing/marionette/harness/marionette_harness/www/test_windows.html delete mode 100644 testing/marionette/harness/marionette_harness/www/white.png delete mode 100644 testing/marionette/harness/marionette_harness/www/windowHandles.html delete mode 100644 testing/marionette/harness/marionette_harness/www/xhtmlTest.html delete mode 100644 testing/marionette/harness/requirements.txt delete mode 100644 testing/marionette/harness/setup.py delete mode 100644 testing/marionette/interaction.js delete mode 100644 testing/marionette/jar.mn delete mode 100644 testing/marionette/l10n.js delete mode 100644 testing/marionette/legacyaction.js delete mode 100644 testing/marionette/listener.js delete mode 100644 testing/marionette/logging.js delete mode 100644 testing/marionette/mach_commands.py delete mode 100644 testing/marionette/mach_test_package_commands.py delete mode 100644 testing/marionette/marionette.eslintrc.js delete mode 100644 testing/marionette/message.js delete mode 100644 testing/marionette/modal.js delete mode 100644 testing/marionette/moz.build delete mode 100644 testing/marionette/navigate.js delete mode 100644 testing/marionette/proxy.js delete mode 100644 testing/marionette/puppeteer/.flake8 delete mode 100644 testing/marionette/puppeteer/firefox/MANIFEST.in delete mode 100644 testing/marionette/puppeteer/firefox/docs/Makefile delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/appinfo.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/keys.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/l10n.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/places.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/security.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/software_update.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/api/utils.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/conf.py delete mode 100644 testing/marionette/puppeteer/firefox/docs/index.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/make.bat delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/about_window/window.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/browser/notifications.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/browser/tabbar.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/browser/toolbars.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/browser/window.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/deck.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/menu.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/pageinfo/window.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/update_wizard/dialog.rst delete mode 100644 testing/marionette/puppeteer/firefox/docs/ui/windows.rst delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/appinfo.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/keys.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/l10n.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/places.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/security.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/api/utils.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/base.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/decorators.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/errors.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/mixins.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/puppeteer.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/about_window/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/about_window/deck.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/about_window/window.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/base.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/notifications.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/tabbar.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/toolbars.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/deck.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/menu.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/pageinfo/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/pageinfo/deck.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/pageinfo/window.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/__init__.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/dialog.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/update_wizard/wizard.py delete mode 100644 testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/windows.py delete mode 100644 testing/marionette/puppeteer/firefox/requirements-docs.txt delete mode 100644 testing/marionette/puppeteer/firefox/requirements.txt delete mode 100644 testing/marionette/puppeteer/firefox/setup.py delete mode 100644 testing/marionette/server.js delete mode 100644 testing/marionette/session.js delete mode 100644 testing/marionette/simpletest.js delete mode 100644 testing/marionette/test_action.js delete mode 100644 testing/marionette/test_assert.js delete mode 100644 testing/marionette/test_element.js delete mode 100644 testing/marionette/test_error.js delete mode 100644 testing/marionette/test_message.js delete mode 100644 testing/marionette/test_navigate.js delete mode 100644 testing/marionette/test_session.js delete mode 100644 testing/marionette/unit.ini diff --git a/old-configure.in b/old-configure.in index 0d617a2236..46a710f9f2 100644 --- a/old-configure.in +++ b/old-configure.in @@ -4540,12 +4540,6 @@ if test "$NECKO_COOKIES"; then _NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_COOKIES" fi -dnl -dnl Always build Marionette -dnl -AC_DEFINE(ENABLE_MARIONETTE) -AC_SUBST(ENABLE_MARIONETTE) - dnl ======================================================== dnl = dnl = Miscellaneous (former toolkit/moz.configure) diff --git a/testing/firefox-ui/.flake8 b/testing/firefox-ui/.flake8 deleted file mode 100644 index ad0819adf8..0000000000 --- a/testing/firefox-ui/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 99 -exclude = __init__.py, diff --git a/testing/firefox-ui/harness/MANIFEST.in b/testing/firefox-ui/harness/MANIFEST.in deleted file mode 100644 index cf628b039c..0000000000 --- a/testing/firefox-ui/harness/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -exclude MANIFEST.in -include requirements.txt diff --git a/testing/firefox-ui/harness/firefox_ui_harness/__init__.py b/testing/firefox-ui/harness/firefox_ui_harness/__init__.py deleted file mode 100644 index 02ae10cdf4..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# 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/. - -__version__ = '1.4.0' - -import cli_functional -import cli_update diff --git a/testing/firefox-ui/harness/firefox_ui_harness/arguments/__init__.py b/testing/firefox-ui/harness/firefox_ui_harness/arguments/__init__.py deleted file mode 100644 index 57dc77f607..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/arguments/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# 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/. - -from firefox_ui_harness.arguments.base import FirefoxUIArguments -from firefox_ui_harness.arguments.update import UpdateArguments diff --git a/testing/firefox-ui/harness/firefox_ui_harness/arguments/base.py b/testing/firefox-ui/harness/firefox_ui_harness/arguments/base.py deleted file mode 100644 index e6427e764d..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/arguments/base.py +++ /dev/null @@ -1,18 +0,0 @@ -# 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/. - -from marionette_harness import BaseMarionetteArguments - - -class FirefoxUIBaseArguments(object): - name = 'Firefox UI Tests' - args = [] - - -class FirefoxUIArguments(BaseMarionetteArguments): - - def __init__(self, **kwargs): - super(FirefoxUIArguments, self).__init__(**kwargs) - - self.register_argument_container(FirefoxUIBaseArguments()) diff --git a/testing/firefox-ui/harness/firefox_ui_harness/arguments/update.py b/testing/firefox-ui/harness/firefox_ui_harness/arguments/update.py deleted file mode 100644 index 9b6d3e5e01..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/arguments/update.py +++ /dev/null @@ -1,65 +0,0 @@ -# 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/. - -from base import FirefoxUIArguments - - -class UpdateBaseArguments(object): - name = 'Firefox UI Update Tests' - args = [ - [['--update-allow-mar-channel'], { - 'dest': 'update_mar_channels', - 'default': [], - 'action': 'append', - 'metavar': 'MAR_CHANNEL', - 'help': 'Additional MAR channel to be allowed for updates, ' - 'e.g. "firefox-mozilla-beta" for updating a release ' - 'build to the latest beta build.' - }], - [['--update-channel'], { - 'dest': 'update_channel', - 'metavar': 'CHANNEL', - 'help': 'Channel to use for the update check.' - }], - [['--update-direct-only'], { - 'dest': 'update_direct_only', - 'default': False, - 'action': 'store_true', - 'help': 'Only perform a direct update' - }], - [['--update-fallback-only'], { - 'dest': 'update_fallback_only', - 'default': False, - 'action': 'store_true', - 'help': 'Only perform a fallback update' - }], - [['--update-override-url'], { - 'dest': 'update_override_url', - 'metavar': 'URL', - 'help': 'Force specified URL to use for update checks.' - }], - [['--update-target-version'], { - 'dest': 'update_target_version', - 'metavar': 'VERSION', - 'help': 'Version of the updated build.' - }], - [['--update-target-buildid'], { - 'dest': 'update_target_buildid', - 'metavar': 'BUILD_ID', - 'help': 'Build ID of the updated build.' - }], - ] - - def verify_usage_handler(self, args): - if args.update_direct_only and args.update_fallback_only: - raise ValueError('Arguments --update-direct-only and --update-fallback-only ' - 'are mutually exclusive.') - - -class UpdateArguments(FirefoxUIArguments): - - def __init__(self, **kwargs): - super(UpdateArguments, self).__init__(**kwargs) - - self.register_argument_container(UpdateBaseArguments()) diff --git a/testing/firefox-ui/harness/firefox_ui_harness/cli_functional.py b/testing/firefox-ui/harness/firefox_ui_harness/cli_functional.py deleted file mode 100644 index e83d88b51e..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/cli_functional.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python - -# 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/. - -from marionette_harness.runtests import cli as mn_cli - -from firefox_ui_harness.arguments import FirefoxUIArguments -from firefox_ui_harness.runners import FirefoxUITestRunner - - -def cli(args=None): - mn_cli(runner_class=FirefoxUITestRunner, - parser_class=FirefoxUIArguments, - args=args, - ) - - -if __name__ == '__main__': - cli() diff --git a/testing/firefox-ui/harness/firefox_ui_harness/cli_update.py b/testing/firefox-ui/harness/firefox_ui_harness/cli_update.py deleted file mode 100644 index 27446a0998..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/cli_update.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python - -# 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/. - -from marionette_harness.runtests import cli as mn_cli - -from firefox_ui_harness.arguments import UpdateArguments -from firefox_ui_harness.runners import UpdateTestRunner - - -def cli(args=None): - mn_cli(runner_class=UpdateTestRunner, - parser_class=UpdateArguments, - args=args, - ) - - -if __name__ == '__main__': - cli() diff --git a/testing/firefox-ui/harness/firefox_ui_harness/runners/__init__.py b/testing/firefox-ui/harness/firefox_ui_harness/runners/__init__.py deleted file mode 100644 index 9022a45b84..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/runners/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# 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/. - -from firefox_ui_harness.runners.base import FirefoxUITestRunner -from firefox_ui_harness.runners.update import UpdateTestRunner diff --git a/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py b/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py deleted file mode 100644 index 66c2a53087..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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 shutil -import tempfile - -import mozfile -import mozinfo - -from marionette_harness import BaseMarionetteTestRunner, MarionetteTestCase - - -class FirefoxUITestRunner(BaseMarionetteTestRunner): - - def __init__(self, **kwargs): - super(FirefoxUITestRunner, self).__init__(**kwargs) - - # select the appropriate GeckoInstance - self.app = 'fxdesktop' - - self.test_handlers = [MarionetteTestCase] - - def duplicate_application(self, application_folder): - """Creates a copy of the specified binary.""" - - if self.workspace: - target_folder = os.path.join(self.workspace_path, 'application.copy') - else: - target_folder = tempfile.mkdtemp('.application.copy') - - self.logger.info('Creating a copy of the application at "%s".' % target_folder) - mozfile.remove(target_folder) - shutil.copytree(application_folder, target_folder) - - return target_folder - - def get_application_folder(self, binary): - """Returns the directory of the application.""" - if mozinfo.isMac: - end_index = binary.find('.app') + 4 - return binary[:end_index] - else: - return os.path.dirname(binary) diff --git a/testing/firefox-ui/harness/firefox_ui_harness/runners/update.py b/testing/firefox-ui/harness/firefox_ui_harness/runners/update.py deleted file mode 100644 index fe4936f68d..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/runners/update.py +++ /dev/null @@ -1,101 +0,0 @@ -# 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 sys - -import mozfile -import mozinstall - -from firefox_ui_harness.runners import FirefoxUITestRunner -from firefox_ui_harness.testcases import UpdateTestCase - - -DEFAULT_PREFS = { - # Bug 1355026: Re-enable when support for the new simplified UI update is available - 'app.update.doorhanger': False, - 'app.update.log': True, - 'startup.homepage_override_url': 'about:blank', -} - - -class UpdateTestRunner(FirefoxUITestRunner): - - def __init__(self, **kwargs): - super(UpdateTestRunner, self).__init__(**kwargs) - - self.original_bin = self.bin - - self.prefs.update(DEFAULT_PREFS) - - # In case of overriding the update URL, set the appropriate preference - override_url = kwargs.pop('update_override_url', None) - if override_url: - self.prefs.update({'app.update.url.override': override_url}) - - self.run_direct_update = not kwargs.pop('update_fallback_only', False) - self.run_fallback_update = not kwargs.pop('update_direct_only', False) - - self.test_handlers = [UpdateTestCase] - - def run_tests(self, tests): - # Used to store the last occurred exception because we execute - # run_tests() multiple times - self.exc_info = None - - failed = 0 - source_folder = self.get_application_folder(self.original_bin) - - results = {} - - def _run_tests(tags): - application_folder = None - - try: - # Backup current tags - test_tags = self.test_tags - - application_folder = self.duplicate_application(source_folder) - self.bin = mozinstall.get_binary(application_folder, 'Firefox') - - self.test_tags = tags - super(UpdateTestRunner, self).run_tests(tests) - - except Exception: - self.exc_info = sys.exc_info() - self.logger.error('Failure during execution of the update test.', - exc_info=self.exc_info) - - finally: - self.test_tags = test_tags - - self.logger.info('Removing copy of the application at "%s"' % application_folder) - try: - mozfile.remove(application_folder) - except IOError as e: - self.logger.error('Cannot remove copy of application: "%s"' % str(e)) - - # Run direct update tests if wanted - if self.run_direct_update: - _run_tests(tags=['direct']) - failed += self.failed - results['Direct'] = False if self.failed else True - - # Run fallback update tests if wanted - if self.run_fallback_update: - _run_tests(tags=['fallback']) - failed += self.failed - results['Fallback'] = False if self.failed else True - - self.logger.info("Summary of update tests:") - for test_type, result in results.iteritems(): - self.logger.info("\t%s update test ran and %s" % - (test_type, 'PASSED' if result else 'FAILED')) - - # Combine failed tests for all run_test() executions - self.failed = failed - - # If exceptions happened, re-throw the last one - if self.exc_info: - ex_type, exception, tb = self.exc_info - raise ex_type, exception, tb diff --git a/testing/firefox-ui/harness/firefox_ui_harness/testcases.py b/testing/firefox-ui/harness/firefox_ui_harness/testcases.py deleted file mode 100644 index abcbd65550..0000000000 --- a/testing/firefox-ui/harness/firefox_ui_harness/testcases.py +++ /dev/null @@ -1,420 +0,0 @@ -# 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 pprint -from datetime import datetime - -import mozfile - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.api.software_update import SoftwareUpdate -from firefox_puppeteer.ui.update_wizard import UpdateWizardDialog -from marionette_driver import Wait -from marionette_driver.errors import NoSuchWindowException -from marionette_harness import MarionetteTestCase - - -class UpdateTestCase(PuppeteerMixin, MarionetteTestCase): - - TIMEOUT_UPDATE_APPLY = 300 - TIMEOUT_UPDATE_CHECK = 30 - TIMEOUT_UPDATE_DOWNLOAD = 720 - - # For the old update wizard, the errors are displayed inside the dialog. For the - # handling of updates in the about window the errors are displayed in new dialogs. - # When the old wizard is open we have to set the preference, so the errors will be - # shown as expected, otherwise we would have unhandled modal dialogs when errors are - # raised. See: - # http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/update/nsUpdateService.js?rev=a9240b1eb2fb#4813 - # http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/update/nsUpdateService.js?rev=a9240b1eb2fb#4756 - PREF_APP_UPDATE_ALTWINDOWTYPE = 'app.update.altwindowtype' - - def __init__(self, *args, **kwargs): - super(UpdateTestCase, self).__init__(*args, **kwargs) - - self.update_channel = kwargs.pop('update_channel') - self.update_mar_channels = set(kwargs.pop('update_mar_channels')) - - self.target_buildid = kwargs.pop('update_target_buildid') - self.target_version = kwargs.pop('update_target_version') - - def setUp(self, is_fallback=False): - super(UpdateTestCase, self).setUp() - - self.software_update = SoftwareUpdate(self.marionette) - self.download_duration = None - - # If a custom update channel has to be set, force a restart of - # Firefox to actually get it applied as a default pref. Use the clean - # option to force a non in_app restart, which would allow Firefox to - # dump the logs to the console. - if self.update_channel: - self.software_update.update_channel = self.update_channel - self.restart(clean=True) - - self.assertEqual(self.software_update.update_channel, self.update_channel) - - # If requested modify the list of allowed MAR channels - if self.update_mar_channels: - self.software_update.mar_channels.add_channels(self.update_mar_channels) - - self.assertTrue(self.update_mar_channels.issubset( - self.software_update.mar_channels.channels), - 'Allowed MAR channels have been set: expected "{}" in "{}"'.format( - ', '.join(self.update_mar_channels), - ', '.join(self.software_update.mar_channels.channels))) - - # Ensure that there exists no already partially downloaded update - self.remove_downloaded_update() - - # Dictionary which holds the information for each update - self.update_status = { - 'build_pre': self.software_update.build_info, - 'build_post': None, - 'fallback': is_fallback, - 'patch': {}, - 'success': False, - } - - # Check if the user has permissions to run the update - self.assertTrue(self.software_update.allowed, - 'Current user has permissions to update the application.') - - def tearDown(self): - try: - self.browser.tabbar.close_all_tabs([self.browser.tabbar.selected_tab]) - - # Add content of the update log file for detailed failures when applying an update - self.update_status['update_log'] = self.read_update_log() - - # Print results for now until we have treeherder integration - output = pprint.pformat(self.update_status) - self.logger.info('Update test results: \n{}'.format(output)) - finally: - super(UpdateTestCase, self).tearDown() - - # Ensure that no trace of an partially downloaded update remain - self.remove_downloaded_update() - - @property - def patch_info(self): - """ Returns information about the active update in the queue. - - :returns: A dictionary with information about the active patch - """ - patch = self.software_update.patch_info - patch['download_duration'] = self.download_duration - - return patch - - def check_for_updates(self, about_window, timeout=TIMEOUT_UPDATE_CHECK): - """Clicks on "Check for Updates" button, and waits for check to complete. - - :param about_window: Instance of :class:`AboutWindow`. - :param timeout: How long to wait for the update check to finish. Optional, - defaults to 60s. - - :returns: True, if an update is available. - """ - self.assertEqual(about_window.deck.selected_panel, - about_window.deck.check_for_updates) - - about_window.deck.check_for_updates.button.click() - Wait(self.marionette, timeout=self.TIMEOUT_UPDATE_CHECK).until( - lambda _: about_window.deck.selected_panel not in - (about_window.deck.check_for_updates, about_window.deck.checking_for_updates), - message='Check for updates has been finished.') - - return about_window.deck.selected_panel != about_window.deck.no_updates_found - - def check_update_applied(self): - """Check that the update has been applied correctly""" - self.update_status['build_post'] = self.software_update.build_info - - # Ensure that the target version is the same or higher. No downgrade - # should have happened. - version_check = self.marionette.execute_script(""" - Components.utils.import("resource://gre/modules/Services.jsm"); - - return Services.vc.compare(arguments[0], arguments[1]); - """, script_args=(self.update_status['build_post']['version'], - self.update_status['build_pre']['version'])) - - self.assertGreaterEqual(version_check, 0, - 'A downgrade from version {} to {} is not allowed'.format( - self.update_status['build_pre']['version'], - self.update_status['build_post']['version'])) - - self.assertNotEqual(self.update_status['build_post']['buildid'], - self.update_status['build_pre']['buildid'], - 'The staged update to buildid {} has not been applied'.format( - self.update_status['patch']['buildid'])) - - self.assertEqual(self.update_status['build_post']['buildid'], - self.update_status['patch']['buildid'], - 'Unexpected target buildid after applying the patch, {} != {}'.format( - self.update_status['build_post']['buildid'], - self.update_status['patch']['buildid'])) - - self.assertEqual(self.update_status['build_post']['locale'], - self.update_status['build_pre']['locale'], - 'Unexpected change of the locale from {} to {}'.format( - self.update_status['build_pre']['locale'], - self.update_status['build_post']['locale'])) - - self.assertEqual(self.update_status['build_post']['disabled_addons'], - self.update_status['build_pre']['disabled_addons'], - 'Application-wide addons have been unexpectedly disabled: {}'.format( - ', '.join(set(self.update_status['build_pre']['locale']) - - set(self.update_status['build_post']['locale'])) - )) - - if self.target_version: - self.assertEqual(self.update_status['build_post']['version'], - self.target_version, - 'Current target version {} does not match expected version {}'.format( - self.update_status['build_post']['version'], self.target_version)) - - if self.target_buildid: - self.assertEqual(self.update_status['build_post']['buildid'], - self.target_buildid, - 'Current target buildid {} does not match expected buildid {}'.format( - self.update_status['build_post']['buildid'], self.target_buildid)) - - self.update_status['success'] = True - - def check_update_not_applied(self): - """Check that the update has not been applied due to a forced invalidation of the patch""" - build_info = self.software_update.build_info - - # Ensure that the version has not been changed - version_check = self.marionette.execute_script(""" - Components.utils.import("resource://gre/modules/Services.jsm"); - - return Services.vc.compare(arguments[0], arguments[1]); - """, script_args=(build_info['version'], - self.update_status['build_pre']['version'])) - - self.assertEqual(version_check, 0, - 'An update from version {} to {} has been unexpectedly applied'.format( - self.update_status['build_pre']['version'], - build_info['version'])) - - # Check that the build id of the source build and the current build are identical - self.assertEqual(build_info['buildid'], - self.update_status['build_pre']['buildid'], - 'The build id has been unexpectedly changed from {} to {}'.format( - self.update_status['build_pre']['buildid'], build_info['buildid'])) - - def download_update(self, window, wait_for_finish=True, timeout=TIMEOUT_UPDATE_DOWNLOAD): - """ Download the update patch. - - :param window: Instance of :class:`AboutWindow` or :class:`UpdateWizardDialog`. - :param wait_for_finish: If True the function has to wait for the download to be finished. - Optional, default to `True`. - :param timeout: How long to wait for the download to finish. Optional, default to 360s. - """ - - def download_via_update_wizard(dialog): - """ Download the update via the old update wizard dialog. - - :param dialog: Instance of :class:`UpdateWizardDialog`. - """ - self.marionette.set_pref(self.PREF_APP_UPDATE_ALTWINDOWTYPE, dialog.window_type) - - try: - # If updates have already been found, proceed to download - if dialog.wizard.selected_panel in [dialog.wizard.updates_found_basic, - dialog.wizard.error_patching, - ]: - dialog.select_next_page() - - # If incompatible add-on are installed, skip over the wizard page - # TODO: Remove once we no longer support version Firefox 45.0ESR - if self.puppeteer.utils.compare_version(self.puppeteer.appinfo.version, - '49.0a1') == -1: - if dialog.wizard.selected_panel == dialog.wizard.incompatible_list: - dialog.select_next_page() - - # Updates were stored in the cache, so no download is necessary - if dialog.wizard.selected_panel in [dialog.wizard.finished, - dialog.wizard.finished_background, - ]: - pass - - # Download the update - elif dialog.wizard.selected_panel == dialog.wizard.downloading: - if wait_for_finish: - start_time = datetime.now() - self.wait_for_download_finished(dialog, timeout) - self.download_duration = (datetime.now() - start_time).total_seconds() - - Wait(self.marionette).until(lambda _: ( - dialog.wizard.selected_panel in [dialog.wizard.finished, - dialog.wizard.finished_background, - ]), - message='Final wizard page has been selected.') - - else: - raise Exception('Invalid wizard page for downloading an update: {}'.format( - dialog.wizard.selected_panel)) - - finally: - self.marionette.clear_pref(self.PREF_APP_UPDATE_ALTWINDOWTYPE) - - # The old update wizard dialog has to be handled differently. It's necessary - # for fallback updates and invalid add-on versions. - if isinstance(window, UpdateWizardDialog): - download_via_update_wizard(window) - return - - if window.deck.selected_panel == window.deck.download_and_install: - window.deck.download_and_install.button.click() - - # Wait for the download to start - Wait(self.marionette).until(lambda _: ( - window.deck.selected_panel != window.deck.download_and_install), - message='Download of the update has been started.') - - if wait_for_finish: - start_time = datetime.now() - self.wait_for_download_finished(window, timeout) - self.download_duration = (datetime.now() - start_time).total_seconds() - - def download_and_apply_available_update(self, force_fallback=False): - """Checks, downloads, and applies an available update. - - :param force_fallback: Optional, if `True` invalidate current update status. - Defaults to `False`. - """ - # Open the about window and check for updates - about_window = self.browser.open_about_window() - - try: - update_available = self.check_for_updates(about_window) - self.assertTrue(update_available, - "Available update has been found") - - # Download update and wait until it has been applied - self.download_update(about_window) - self.wait_for_update_applied(about_window) - - finally: - self.update_status['patch'] = self.patch_info - - if force_fallback: - # Set the downloaded update into failed state - self.software_update.force_fallback() - - # Restart Firefox to apply the downloaded update - self.restart() - - def download_and_apply_forced_update(self): - self.check_update_not_applied() - - # The update wizard dialog opens automatically after the restart but with a short delay - dialog = Wait(self.marionette, ignored_exceptions=[NoSuchWindowException]).until( - lambda _: self.puppeteer.windows.switch_to(lambda win: type(win) is UpdateWizardDialog) - ) - - # In case of a broken complete update the about window has to be used - if self.update_status['patch']['is_complete']: - about_window = None - try: - self.assertEqual(dialog.wizard.selected_panel, - dialog.wizard.error) - dialog.close() - - # Open the about window and check for updates - about_window = self.browser.open_about_window() - update_available = self.check_for_updates(about_window) - self.assertTrue(update_available, - 'Available update has been found') - - # Download update and wait until it has been applied - self.download_update(about_window) - self.wait_for_update_applied(about_window) - - finally: - if about_window: - self.update_status['patch'] = self.patch_info - - else: - try: - self.assertEqual(dialog.wizard.selected_panel, - dialog.wizard.error_patching) - - # Start downloading the fallback update - self.download_update(dialog) - - finally: - self.update_status['patch'] = self.patch_info - - # Restart Firefox to apply the update - self.restart() - - def read_update_log(self): - """Read the content of the update log file for the last update attempt.""" - path = os.path.join(os.path.dirname(self.software_update.staging_directory), - 'last-update.log') - try: - with open(path, 'rb') as f: - return f.read().splitlines() - except IOError as exc: - self.logger.warning(str(exc)) - return None - - def remove_downloaded_update(self): - """Remove an already downloaded update from the update staging directory. - - Hereby not only remove the update subdir but everything below 'updates'. - """ - path = os.path.dirname(self.software_update.staging_directory) - self.logger.info('Clean-up update staging directory: {}'.format(path)) - mozfile.remove(path) - - def wait_for_download_finished(self, window, timeout=TIMEOUT_UPDATE_DOWNLOAD): - """ Waits until download is completed. - - :param window: Instance of :class:`AboutWindow` or :class:`UpdateWizardDialog`. - :param timeout: How long to wait for the download to finish. Optional, - default to 360 seconds. - """ - # The old update wizard dialog has to be handled differently. It's necessary - # for fallback updates and invalid add-on versions. - if isinstance(window, UpdateWizardDialog): - Wait(self.marionette, timeout=timeout).until( - lambda _: window.wizard.selected_panel != window.wizard.downloading, - message='Download has been completed.') - - self.assertNotIn(window.wizard.selected_panel, - [window.wizard.error, window.wizard.error_extra]) - return - - Wait(self.marionette, timeout=timeout).until( - lambda _: window.deck.selected_panel not in - (window.deck.download_and_install, window.deck.downloading), - message='Download has been completed.') - - self.assertNotEqual(window.deck.selected_panel, - window.deck.download_failed) - - def wait_for_update_applied(self, about_window, timeout=TIMEOUT_UPDATE_APPLY): - """ Waits until the downloaded update has been applied. - - :param about_window: Instance of :class:`AboutWindow`. - :param timeout: How long to wait for the update to apply. Optional, - default to 300 seconds - """ - Wait(self.marionette, timeout=timeout).until( - lambda _: about_window.deck.selected_panel == about_window.deck.apply, - message='Final wizard page has been selected.') - - # Wait for update to be staged because for update tests we modify the update - # status file to enforce the fallback update. If we modify the file before - # Firefox does, Firefox will override our change and we will have no fallback update. - Wait(self.marionette, timeout=timeout).until( - lambda _: 'applied' in self.software_update.active_update.state, - message='Update has been applied.') diff --git a/testing/firefox-ui/harness/requirements.txt b/testing/firefox-ui/harness/requirements.txt deleted file mode 100644 index 54114debb9..0000000000 --- a/testing/firefox-ui/harness/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -firefox-puppeteer >= 52.1.0, <53.0.0 -marionette-harness >= 4.0.0 -mozfile >= 1.2 -mozinfo >= 0.8 -mozinstall >= 1.12 diff --git a/testing/firefox-ui/harness/setup.py b/testing/firefox-ui/harness/setup.py deleted file mode 100644 index 1799d50578..0000000000 --- a/testing/firefox-ui/harness/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -# 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 setup, find_packages - -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('firefox_ui_harness', '__init__.py'), re.M)[0] - -long_description = """Custom Marionette runner classes and entry scripts for Firefox Desktop -specific Marionette tests. -""" - -setup(name='firefox-ui-harness', - version=get_version(), - description="Firefox UI Harness", - long_description=long_description, - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers - keywords='mozilla', - author='Auto-tools', - author_email='tools-marionette@lists.mozilla.org', - url='https://wiki.mozilla.org/Auto-tools/Projects/Marionette/Harnesses/FirefoxUI', - license='MPL', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=read('requirements.txt').splitlines(), - entry_points=""" - [console_scripts] - firefox-ui-functional = firefox_ui_harness.cli_functional:cli - firefox-ui-update = firefox_ui_harness.cli_update:cli - """, - ) diff --git a/testing/firefox-ui/mach_commands.py b/testing/firefox-ui/mach_commands.py deleted file mode 100644 index 368b673a22..0000000000 --- a/testing/firefox-ui/mach_commands.py +++ /dev/null @@ -1,120 +0,0 @@ -# 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/. - -from __future__ import absolute_import, unicode_literals - -import os -import sys - -from mozbuild.base import ( - MachCommandBase, - MachCommandConditions as conditions, -) - -from mach.decorators import ( - Command, - CommandProvider, -) - - -def setup_argument_parser_functional(): - from firefox_ui_harness.arguments.base import FirefoxUIArguments - from mozlog.structured import commandline - parser = FirefoxUIArguments() - commandline.add_logging_group(parser) - return parser - - -def setup_argument_parser_update(): - from firefox_ui_harness.arguments.update import UpdateArguments - from mozlog.structured import commandline - parser = UpdateArguments() - commandline.add_logging_group(parser) - return parser - - -def run_firefox_ui_test(testtype=None, topsrcdir=None, **kwargs): - from mozlog.structured import commandline - from argparse import Namespace - import firefox_ui_harness - - if testtype == 'functional': - parser = setup_argument_parser_functional() - else: - parser = setup_argument_parser_update() - - test_types = { - 'functional': { - 'default_tests': [ - os.path.join('puppeteer', 'manifest.ini'), - os.path.join('functional', 'manifest.ini'), - ], - 'cli_module': firefox_ui_harness.cli_functional, - }, - 'update': { - 'default_tests': [ - os.path.join('update', 'manifest.ini'), - ], - 'cli_module': firefox_ui_harness.cli_update, - } - } - - fxui_dir = os.path.join(topsrcdir, 'testing', 'firefox-ui') - - # Set the resources path which is used to serve test data via wptserve - if not kwargs['server_root']: - kwargs['server_root'] = os.path.join(fxui_dir, 'resources') - - # If called via "mach test" a dictionary of tests is passed in - if 'test_objects' in kwargs: - tests = [] - for obj in kwargs['test_objects']: - tests.append(obj['file_relpath']) - kwargs['tests'] = tests - elif not kwargs.get('tests'): - # If no tests have been selected, set default ones - kwargs['tests'] = [os.path.join(fxui_dir, 'tests', test) - for test in test_types[testtype]['default_tests']] - - kwargs['logger'] = commandline.setup_logging('Firefox UI - {} Tests'.format(testtype), - {"mach": sys.stdout}) - - args = Namespace() - - for k, v in kwargs.iteritems(): - setattr(args, k, v) - - parser.verify_usage(args) - - failed = test_types[testtype]['cli_module'].cli(args=vars(args)) - - if failed > 0: - return 1 - else: - return 0 - - -@CommandProvider -class MachCommands(MachCommandBase): - """Mach command provider for Firefox ui tests.""" - - @Command('firefox-ui-functional', category='testing', - conditions=[conditions.is_firefox], - description='Run the functional test suite of Firefox UI tests.', - parser=setup_argument_parser_functional, - ) - def run_firefox_ui_functional(self, **kwargs): - kwargs['binary'] = kwargs['binary'] or self.get_binary_path('app') - return run_firefox_ui_test(testtype='functional', - topsrcdir=self.topsrcdir, **kwargs) - - @Command('firefox-ui-update', category='testing', - conditions=[conditions.is_firefox], - description='Run the update test suite of Firefox UI tests.', - parser=setup_argument_parser_update, - ) - def run_firefox_ui_update(self, **kwargs): - kwargs['binary'] = kwargs['binary'] or self.get_binary_path('app') - return run_firefox_ui_test(testtype='update', - topsrcdir=self.topsrcdir, **kwargs) diff --git a/testing/firefox-ui/moz.build b/testing/firefox-ui/moz.build deleted file mode 100644 index dd7311c038..0000000000 --- a/testing/firefox-ui/moz.build +++ /dev/null @@ -1,11 +0,0 @@ -# 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/. - -FIREFOX_UI_FUNCTIONAL_MANIFESTS += ["tests/functional/manifest.ini"] -FIREFOX_UI_UPDATE_MANIFESTS += ["tests/update/manifest.ini"] -# TODO: Move to testing/marionette/puppeteer/firefox -PUPPETEER_FIREFOX_MANIFESTS += ["tests/puppeteer/manifest.ini"] - -with Files("**"): - BUG_COMPONENT = ("Testing", "Firefox UI Tests") diff --git a/testing/firefox-ui/resources/addons/extensions/restartless_addon_signed.xpi b/testing/firefox-ui/resources/addons/extensions/restartless_addon_signed.xpi deleted file mode 100644 index ed86213e79..0000000000 Binary files a/testing/firefox-ui/resources/addons/extensions/restartless_addon_signed.xpi and /dev/null differ diff --git a/testing/firefox-ui/resources/addons/extensions/restartless_addon_unsigned.xpi b/testing/firefox-ui/resources/addons/extensions/restartless_addon_unsigned.xpi deleted file mode 100644 index d0768103d5..0000000000 Binary files a/testing/firefox-ui/resources/addons/extensions/restartless_addon_unsigned.xpi and /dev/null differ diff --git a/testing/firefox-ui/resources/cookies/cookie_single.html b/testing/firefox-ui/resources/cookies/cookie_single.html deleted file mode 100644 index d4a02b45b8..0000000000 --- a/testing/firefox-ui/resources/cookies/cookie_single.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - diff --git a/testing/firefox-ui/resources/images/firefox_favicon.ico b/testing/firefox-ui/resources/images/firefox_favicon.ico deleted file mode 100644 index 2c2f81768d..0000000000 Binary files a/testing/firefox-ui/resources/images/firefox_favicon.ico and /dev/null differ diff --git a/testing/firefox-ui/resources/images/mozilla_favicon.ico b/testing/firefox-ui/resources/images/mozilla_favicon.ico deleted file mode 100644 index d44438903b..0000000000 Binary files a/testing/firefox-ui/resources/images/mozilla_favicon.ico and /dev/null differ diff --git a/testing/firefox-ui/resources/images/mozilla_logo.jpg b/testing/firefox-ui/resources/images/mozilla_logo.jpg deleted file mode 100644 index 231b385ee4..0000000000 Binary files a/testing/firefox-ui/resources/images/mozilla_logo.jpg and /dev/null differ diff --git a/testing/firefox-ui/resources/layout/mozilla.html b/testing/firefox-ui/resources/layout/mozilla.html deleted file mode 100644 index 9224533bf0..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - Mozilla - - - - - - - - - Community | - Project | - Organization - -
-

- We believe that the internet should be public, - open and accessible. -

- -

Community

-

- We're a global community of thousands who believe in the power - of technology to enrich people's lives. - More -

- -

Project

-

- We're an open source project whose code is used for some of the - Internet's most innovative applications. - More -

- -

Organization

-

- We're a public benefit organization dedicated to making the - Internet better for everyone. - More -

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_community.html b/testing/firefox-ui/resources/layout/mozilla_community.html deleted file mode 100644 index c8da6afd84..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_community.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - Mozilla Community - - - - - - - - - History | - Communicate | - More - -
-

Our Community

- -

History

-

- When www.mozilla.org was launched in 1998 all community activity - occurred right here on this site. Since then the community has - grown much bigger and there are now many different sites, - forums, blogs and newsgroups in different places that track - different parts of the project. These pages aim to be a - comprehensive list to all of the different community resources - available. If you know of something that's not on these lists - that should be, please contact us and we'll update these - pages. -

- -

Communicate

-

- There are a number of different ways community members - communicate and coordinate (people use mailing lists and - newsgroups, blogs, forums, wikis and they even meet in real - life sometimes too) and all of these options might be - overwhelming at first. Hopefully this set of links will provide - some useful pointers to help you figure out where to go to find - what you're looking for. If you do get lost though and need - some help, feel free to ask for more information. -

- -

More

-

- Please note that this is intended to be an entry point that - provides a high-level overview of the different community areas. - If you're looking for more detailed information about a specific - topic, please look at our Developer, - Contribute and Support - pages or take a look at the other information referenced - throughout this site. -

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_contribute.html b/testing/firefox-ui/resources/layout/mozilla_contribute.html deleted file mode 100644 index cf5e54b85f..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_contribute.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - Mozilla Contribute - - - - - - - - - Summary | - Contribute - -
-

Get Involved

- -

Summary

-

- You can build a better Internet - by getting involved with Mozilla. You don't have to be a C++ - guru (or even know what that means!) and you don't need to spend - lots of time. Take a look at the opportunities below and feel - free to ask if you have any questions. -

- -

Contribute

-

-

Area of Interest

- Browse contribution opportunities by area of interest. - - -

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_governance.html b/testing/firefox-ui/resources/layout/mozilla_governance.html deleted file mode 100644 index 8e25aaabde..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_governance.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - Mozilla Governance - - - - - - - - - Summary | - More - -
-

Governance

- -

Summary

-

- Mozilla is an open source project governed as a meritocracy. Our - community is structured as a virtual organization where - authority is distributed to both volunteer and employed - community members as they show their abilities through - contributions to the project. -

- -

More

-

-

-

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_grants.html b/testing/firefox-ui/resources/layout/mozilla_grants.html deleted file mode 100644 index c8935c4fb5..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_grants.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - Mozilla Grants - - - - - - - - - Summary | - Goals - -
-

Mozilla Grants

- -

Summary

-

- Since 2006, Mozilla has awarded over two million dollars to fund - projects that contribute to the health of the Open Web. The - Mozilla Grants program is jointly funded by the Mozilla - Corporation and the Mozilla Foundation, and awards financial - support to individuals and organizations whose work supports and - enhances the mission and values of the Mozilla Project. -

- -

Goals

-

- Mozilla makes grants to individuals and organizations all over - the world. We mainly fund activity that supports the Mozilla - Grants program's four target areas: - -

-

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_mission.html b/testing/firefox-ui/resources/layout/mozilla_mission.html deleted file mode 100644 index c9ed2bd850..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_mission.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - Mozilla Mission - - - - - - - - - Mission | - Organization | - Goal - -
-

Mission

- -

Mission

-

- Mozilla's mission is to promote openness, innovation, - and opportunity on the web. We do this by creating - great software, like the Firefox browser, and building - movements, like Drumbeat, that give people tools to take control - of their online lives. -

- -

Organization

-

- As a non-profit organization, we define success in terms of - building communities and enriching people's lives instead of - benefiting our shareholders (guess what: we don't even have - shareholders). We believe in the power and potential of the - Internet and want to see it thrive for everyone, everywhere. -

- -

Goal

-

- - Building a better Internet is an ambitious goal, but we - believe that it is possible - - when people who share our passion get involved. Coders, artists, - writers, testers, surfers, students, grandparents; anyone who - uses and cares about the web can help make it even better. - Find out how you can help. -

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_organizations.html b/testing/firefox-ui/resources/layout/mozilla_organizations.html deleted file mode 100644 index 9d2ae9ff08..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_organizations.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - Mozilla Organizations - - - - - - - - - Summary | - Organization - -
-

Mozilla Organizations

- -

Summary

-

- Mozilla is a global community of people creating a better - Internet. We build public benefit into the Internet by creating - free, open source products and technologies that improve the - online experience for people everywhere. -

- -

Organization

-

- There are several organizations that support the Mozilla - community and Mozilla's principles. They include the non-profit - Mozilla Foundation as well as two wholly owned taxable - subsidiaries, the Mozilla Corporation and Mozilla Messaging. - Mozilla considers itself a hybrid organization, combining non- - profit and market strategies to ensure the Internet remains a - shared public resource. -

-
- - diff --git a/testing/firefox-ui/resources/layout/mozilla_projects.html b/testing/firefox-ui/resources/layout/mozilla_projects.html deleted file mode 100644 index a4ec7c8409..0000000000 --- a/testing/firefox-ui/resources/layout/mozilla_projects.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - Mozilla Projects - - - - - - - - - Summary | - Applications - -
-

Our Projects

- -

Summary

-

- The Mozilla community produces a lot of great software and acts - as an incubator for innovative ideas as a way to advance our - mission of building a better - Internet. -

- -

Applications

-

-

- These applications are developed by the Mozilla community - and their code is hosted on mozilla.org. -

- - -

-
- - diff --git a/testing/firefox-ui/resources/private_browsing/about.html b/testing/firefox-ui/resources/private_browsing/about.html deleted file mode 100644 index 30b211be69..0000000000 --- a/testing/firefox-ui/resources/private_browsing/about.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - -
About Private Browsing
- - diff --git a/testing/firefox-ui/resources/security/enable_privilege.html b/testing/firefox-ui/resources/security/enable_privilege.html deleted file mode 100644 index 9d18e46848..0000000000 --- a/testing/firefox-ui/resources/security/enable_privilege.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - Test page for enablePrivilege - - - -

- - diff --git a/testing/firefox-ui/resources/support.html b/testing/firefox-ui/resources/support.html deleted file mode 100644 index b794e9ef92..0000000000 --- a/testing/firefox-ui/resources/support.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
- - diff --git a/testing/firefox-ui/tests/functional/keyboard_shortcuts/manifest.ini b/testing/firefox-ui/tests/functional/keyboard_shortcuts/manifest.ini deleted file mode 100644 index 97ec827f17..0000000000 --- a/testing/firefox-ui/tests/functional/keyboard_shortcuts/manifest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -tags = local - -[test_browser_window.py] diff --git a/testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py b/testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py deleted file mode 100644 index 5b656d0e5f..0000000000 --- a/testing/firefox-ui/tests/functional/keyboard_shortcuts/test_browser_window.py +++ /dev/null @@ -1,56 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestBrowserWindowShortcuts(PuppeteerMixin, MarionetteTestCase): - - def test_addons_manager(self): - # If an about:xyz page is visible, no new tab will be opened - with self.marionette.using_context('content'): - self.marionette.navigate('about:') - - # TODO: To be moved to the upcoming add-ons library - def opener(tab): - tab.window.send_shortcut(tab.window.localize_entity('addons.commandkey'), - accel=True, shift=True) - self.browser.tabbar.open_tab(opener) - - # TODO: Marionette currently fails to detect the correct tab - # with self.marionette.using_content('content'): - # self.wait_for_condition(lambda mn: mn.get_url() == "about:addons") - - # TODO: remove extra switch once it is done automatically - self.browser.tabbar.tabs[1].switch_to() - self.browser.tabbar.close_tab() - - def test_search_field(self): - current_name = self.marionette.execute_script(""" - return window.document.activeElement.localName; - """) - - # This doesn't test anything if we're already at input. - self.assertNotEqual(current_name, "input") - - # TODO: To be moved to the upcoming search library - if self.puppeteer.platform == 'linux': - key = 'searchFocusUnix.commandkey' - else: - key = 'searchFocus.commandkey' - self.browser.send_shortcut(self.browser.localize_entity(key), - accel=True) - - # TODO: Check that the right input box is focused - # Located below searchbar as class="autocomplete-textbox textbox-input" - # Anon locator has not been released yet (bug 1080764) - def has_input_selected(mn): - selection_name = mn.execute_script(""" - return window.document.activeElement.localName; - """) - return selection_name == "input" - - Wait(self.marionette).until(has_input_selected) diff --git a/testing/firefox-ui/tests/functional/locationbar/manifest.ini b/testing/firefox-ui/tests/functional/locationbar/manifest.ini deleted file mode 100644 index 72adfd767f..0000000000 --- a/testing/firefox-ui/tests/functional/locationbar/manifest.ini +++ /dev/null @@ -1,9 +0,0 @@ -[DEFAULT] -tags = local - -[test_access_locationbar.py] -disabled = Bug 1168727 - Timeout when opening auto-complete popup -[test_escape_autocomplete.py] -[test_favicon_in_autocomplete.py] -[test_suggest_bookmarks.py] - diff --git a/testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py b/testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py deleted file mode 100644 index 160a402c20..0000000000 --- a/testing/firefox-ui/tests/functional/locationbar/test_access_locationbar.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestAccessLocationBar(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestAccessLocationBar, self).setUp() - - # Clear complete history so there's no interference from previous entries. - self.puppeteer.places.remove_all_history() - - self.test_urls = [ - 'layout/mozilla_projects.html', - 'layout/mozilla.html', - 'layout/mozilla_mission.html' - ] - self.test_urls = [self.marionette.absolute_url(t) - for t in self.test_urls] - - self.locationbar = self.browser.navbar.locationbar - self.autocomplete_results = self.locationbar.autocomplete_results - self.urlbar = self.locationbar.urlbar - - def test_access_locationbar_history(self): - - # Open some local pages, then about:blank - def load_urls(): - with self.marionette.using_context('content'): - for url in self.test_urls: - self.marionette.navigate(url) - self.puppeteer.places.wait_for_visited(self.test_urls, load_urls) - with self.marionette.using_context('content'): - self.marionette.navigate('about:blank') - - # Need to blur url bar or autocomplete won't load - bug 1038614 - self.marionette.execute_script("""arguments[0].blur();""", script_args=[self.urlbar]) - - # Clear contents of url bar to focus, then arrow down for list of visited sites - # Verify that autocomplete is open and results are displayed - self.locationbar.clear() - self.urlbar.send_keys(self.puppeteer.keys.ARROW_DOWN) - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open) - Wait(self.marionette).until(lambda _: len(self.autocomplete_results.visible_results) > 1) - - # Arrow down again to select first item in list, appearing in reversed order, as loaded. - # Verify first item. - self.urlbar.send_keys(self.puppeteer.keys.ARROW_DOWN) - Wait(self.marionette).until(lambda _: self.autocomplete_results.selected_index == '0') - self.assertIn('mission', self.locationbar.value) - - # Navigate to the currently selected url - # Verify it loads by comparing the page url to the test url - self.urlbar.send_keys(self.puppeteer.keys.ENTER) - self.assertEqual(self.locationbar.value, self.test_urls[-1]) diff --git a/testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py b/testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py deleted file mode 100644 index 209d9b0f5f..0000000000 --- a/testing/firefox-ui/tests/functional/locationbar/test_escape_autocomplete.py +++ /dev/null @@ -1,56 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestEscapeAutocomplete(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestEscapeAutocomplete, self).setUp() - - # Clear complete history so there's no interference from previous entries. - self.puppeteer.places.remove_all_history() - - self.test_urls = [ - 'layout/mozilla.html', - 'layout/mozilla_community.html', - ] - self.test_urls = [self.marionette.absolute_url(t) - for t in self.test_urls] - - self.test_string = 'mozilla' - - self.locationbar = self.browser.navbar.locationbar - self.autocomplete_results = self.locationbar.autocomplete_results - - def tearDown(self): - self.autocomplete_results.close(force=True) - - super(TestEscapeAutocomplete, self).tearDown() - - def test_escape_autocomplete(self): - # Open some local pages - def load_urls(): - with self.marionette.using_context('content'): - for url in self.test_urls: - self.marionette.navigate(url) - self.puppeteer.places.wait_for_visited(self.test_urls, load_urls) - - # Clear the location bar, type the test string, check that autocomplete list opens - self.locationbar.clear() - self.locationbar.urlbar.send_keys(self.test_string) - self.assertEqual(self.locationbar.value, self.test_string) - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open) - - # Press escape, check location bar value, check autocomplete list closed - self.locationbar.urlbar.send_keys(self.puppeteer.keys.ESCAPE) - self.assertEqual(self.locationbar.value, self.test_string) - Wait(self.marionette).until(lambda _: not self.autocomplete_results.is_open) - - # Press escape again and check that locationbar returns to the page url - self.locationbar.urlbar.send_keys(self.puppeteer.keys.ESCAPE) - self.assertEqual(self.locationbar.value, self.test_urls[-1]) diff --git a/testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py b/testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py deleted file mode 100644 index 6e8a5f6b12..0000000000 --- a/testing/firefox-ui/tests/functional/locationbar/test_favicon_in_autocomplete.py +++ /dev/null @@ -1,62 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestFaviconInAutocomplete(PuppeteerMixin, MarionetteTestCase): - - PREF_SUGGEST_SEARCHES = 'browser.urlbar.suggest.searches' - PREF_SUGGEST_BOOKMARK = 'browser.urlbar.suggest.bookmark' - - def setUp(self): - super(TestFaviconInAutocomplete, self).setUp() - - # Disable suggestions for searches and bookmarks to get results only for history - self.marionette.set_pref(self.PREF_SUGGEST_SEARCHES, False) - self.marionette.set_pref(self.PREF_SUGGEST_BOOKMARK, False) - - self.puppeteer.places.remove_all_history() - - self.test_urls = [self.marionette.absolute_url('layout/mozilla.html')] - - self.test_string = 'mozilla' - self.test_favicon = 'mozilla_favicon.ico' - - self.autocomplete_results = self.browser.navbar.locationbar.autocomplete_results - - def tearDown(self): - try: - self.autocomplete_results.close(force=True) - self.marionette.clear_pref(self.PREF_SUGGEST_SEARCHES) - self.marionette.clear_pref(self.PREF_SUGGEST_BOOKMARK) - finally: - super(TestFaviconInAutocomplete, self).tearDown() - - def test_favicon_in_autocomplete(self): - # Open the test page - def load_urls(): - with self.marionette.using_context('content'): - self.marionette.navigate(self.test_urls[0]) - self.puppeteer.places.wait_for_visited(self.test_urls, load_urls) - - locationbar = self.browser.navbar.locationbar - - # Clear the location bar, type the test string, check that autocomplete list opens - locationbar.clear() - locationbar.urlbar.send_keys(self.test_string) - self.assertEqual(locationbar.value, self.test_string) - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_complete) - - result = self.autocomplete_results.visible_results[1] - - result_icon = self.marionette.execute_script(""" - return arguments[0].image; - """, script_args=[result]) - - self.assertIn(self.test_favicon, result_icon) - - self.autocomplete_results.close() diff --git a/testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py b/testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py deleted file mode 100644 index 9abc2d6cb9..0000000000 --- a/testing/firefox-ui/tests/functional/locationbar/test_suggest_bookmarks.py +++ /dev/null @@ -1,96 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, Wait -from marionette_harness import MarionetteTestCase - - -class TestStarInAutocomplete(PuppeteerMixin, MarionetteTestCase): - """ This replaces - http://hg.mozilla.org/qa/mozmill-tests/file/default/firefox/tests/functional/testAwesomeBar/testSuggestBookmarks.js - Check a star appears in autocomplete list for a bookmarked page. - """ - - PREF_SUGGEST_SEARCHES = 'browser.urlbar.suggest.searches' - - def setUp(self): - super(TestStarInAutocomplete, self).setUp() - - self.bookmark_panel = None - self.test_urls = [self.marionette.absolute_url('layout/mozilla_grants.html')] - - # Disable search suggestions to only get results for history and bookmarks - self.marionette.set_pref(self.PREF_SUGGEST_SEARCHES, False) - - with self.marionette.using_context('content'): - self.marionette.navigate('about:blank') - - self.puppeteer.places.remove_all_history() - - def tearDown(self): - # Close the autocomplete results - try: - if self.bookmark_panel: - self.marionette.execute_script(""" - arguments[0].hidePopup(); - """, script_args=[self.bookmark_panel]) - - self.browser.navbar.locationbar.autocomplete_results.close() - self.puppeteer.places.restore_default_bookmarks() - self.marionette.clear_pref(self.PREF_SUGGEST_SEARCHES) - finally: - super(TestStarInAutocomplete, self).tearDown() - - def test_star_in_autocomplete(self): - search_string = 'grants' - - def visit_urls(): - with self.marionette.using_context('content'): - for url in self.test_urls: - self.marionette.navigate(url) - - # Navigate to all the urls specified in self.test_urls and wait for them to - # be registered as visited - self.puppeteer.places.wait_for_visited(self.test_urls, visit_urls) - - # Bookmark the current page using the bookmark menu - self.browser.menubar.select_by_id('bookmarksMenu', - 'menu_bookmarkThisPage') - - # TODO: Replace hard-coded selector with library method when one is available - self.bookmark_panel = self.marionette.find_element(By.ID, 'editBookmarkPanel') - done_button = self.marionette.find_element(By.ID, 'editBookmarkPanelDoneButton') - - Wait(self.marionette).until( - lambda mn: self.bookmark_panel.get_attribute('panelopen') == 'true') - done_button.click() - - # We must open the blank page so the autocomplete result isn't "Switch to tab" - with self.marionette.using_context('content'): - self.marionette.navigate('about:blank') - - self.puppeteer.places.remove_all_history() - - # Focus the locationbar, delete any contents there, and type the search string - locationbar = self.browser.navbar.locationbar - locationbar.clear() - locationbar.urlbar.send_keys(search_string) - autocomplete_results = locationbar.autocomplete_results - - # Wait for the search string to be present, for the autocomplete results to appear - # and for there to be exactly one autocomplete result - Wait(self.marionette).until(lambda mn: locationbar.value == search_string) - Wait(self.marionette).until(lambda mn: autocomplete_results.is_complete) - Wait(self.marionette).until(lambda mn: len(autocomplete_results.visible_results) == 2) - - # Compare the highlighted text in the autocomplete result to the search string - first_result = autocomplete_results.visible_results[1] - matching_titles = autocomplete_results.get_matching_text(first_result, 'title') - for title in matching_titles: - Wait(self.marionette).until(lambda mn: title.lower() == search_string) - - self.assertIn('bookmark', - first_result.get_attribute('type'), - 'The auto-complete result is a bookmark') diff --git a/testing/firefox-ui/tests/functional/manifest.ini b/testing/firefox-ui/tests/functional/manifest.ini deleted file mode 100644 index bc254e9629..0000000000 --- a/testing/firefox-ui/tests/functional/manifest.ini +++ /dev/null @@ -1,5 +0,0 @@ -[include:keyboard_shortcuts/manifest.ini] -[include:locationbar/manifest.ini] -[include:private_browsing/manifest.ini] -[include:security/manifest.ini] -[include:sessionstore/manifest.ini] diff --git a/testing/firefox-ui/tests/functional/private_browsing/manifest.ini b/testing/firefox-ui/tests/functional/private_browsing/manifest.ini deleted file mode 100644 index 4057530827..0000000000 --- a/testing/firefox-ui/tests/functional/private_browsing/manifest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -tags = local - -[test_about_private_browsing.py] \ No newline at end of file diff --git a/testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py b/testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py deleted file mode 100644 index 4b22d03ea9..0000000000 --- a/testing/firefox-ui/tests/functional/private_browsing/test_about_private_browsing.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.ui.browser.window import BrowserWindow -from marionette_driver import By, Wait -from marionette_harness import MarionetteTestCase - - -class TestAboutPrivateBrowsing(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestAboutPrivateBrowsing, self).setUp() - - # Use a fake local support URL - support_url = 'about:blank?' - self.marionette.set_pref('app.support.baseURL', support_url) - - self.pb_url = support_url + 'private-browsing' - - def tearDown(self): - try: - self.marionette.clear_pref('app.support.baseURL') - finally: - super(TestAboutPrivateBrowsing, self).tearDown() - - def testCheckAboutPrivateBrowsing(self): - self.assertFalse(self.browser.is_private) - - with self.marionette.using_context('content'): - self.marionette.navigate('about:privatebrowsing') - - status_node = self.marionette.find_element(By.CSS_SELECTOR, 'p.showNormal') - self.assertEqual(status_node.text, - self.browser.localize_entity('aboutPrivateBrowsing.notPrivate'), - 'Status text indicates we are not in private browsing mode') - - def window_opener(win): - with win.marionette.using_context('content'): - button = self.marionette.find_element(By.ID, 'startPrivateBrowsing') - button.click() - - pb_window = self.browser.open_window(callback=window_opener, - expected_window_class=BrowserWindow) - - try: - self.assertTrue(pb_window.is_private) - - def tab_opener(tab): - with tab.marionette.using_context('content'): - link = tab.marionette.find_element(By.ID, 'learnMore') - link.click() - - tab = pb_window.tabbar.open_tab(trigger=tab_opener) - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda _: tab.location == self.pb_url) - - finally: - pb_window.close() diff --git a/testing/firefox-ui/tests/functional/security/manifest.ini b/testing/firefox-ui/tests/functional/security/manifest.ini deleted file mode 100644 index 46aeaf5c31..0000000000 --- a/testing/firefox-ui/tests/functional/security/manifest.ini +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -tags = remote - -[test_dv_certificate.py] -[test_enable_privilege.py] -tags = local -[test_ev_certificate.py] -skip-if = true # Bug 1407663 -[test_mixed_content_page.py] -[test_mixed_script_content_blocking.py] -[test_no_certificate.py] -tags = local -[test_safe_browsing_initial_download.py] -[test_safe_browsing_notification.py] -[test_safe_browsing_warning_pages.py] -[test_security_notification.py] -[test_ssl_disabled_error_page.py] -[test_ssl_status_after_restart.py] -skip-if = (os == "win" && os_version == "5.1") # Bug 1167179: Fails to open popups after restart -[test_submit_unencrypted_info_warning.py] -[test_unknown_issuer.py] -[test_untrusted_connection_error_page.py] diff --git a/testing/firefox-ui/tests/functional/security/test_dv_certificate.py b/testing/firefox-ui/tests/functional/security/test_dv_certificate.py deleted file mode 100644 index 565f64996e..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_dv_certificate.py +++ /dev/null @@ -1,85 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestDVCertificate(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestDVCertificate, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.browser.navbar.locationbar.identity_popup - - self.url = 'https://ssl-dv.mozqa.com' - - def tearDown(self): - try: - self.browser.switch_to() - self.identity_popup.close(force=True) - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestDVCertificate, self).tearDown() - - def test_dv_cert(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.assertEqual(self.locationbar.identity_box.get_property('className'), - 'verifiedDomain') - - # Open the identity popup - self.locationbar.open_identity_popup() - - # Check the identity popup doorhanger - self.assertEqual(self.identity_popup.element.get_attribute('connection'), 'secure') - - cert = self.browser.tabbar.selected_tab.certificate - - # The shown host equals to the certificate - self.assertEqual(self.identity_popup.view.main.host.get_property('textContent'), - cert['commonName']) - - # Only the secure label is visible in the main view - secure_label = self.identity_popup.view.main.secure_connection_label - self.assertNotEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.main.insecure_connection_label - self.assertEqual(insecure_label.value_of_css_property('display'), 'none') - - self.identity_popup.view.main.expander.click() - Wait(self.marionette).until( - lambda _: self.identity_popup.view.security.selected, - message='Security view of identity popup has not been selected.') - - # Only the secure label is visible in the security view - secure_label = self.identity_popup.view.security.secure_connection_label - self.assertNotEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.security.insecure_connection_label - self.assertEqual(insecure_label.value_of_css_property('display'), 'none') - - verifier_label = self.browser.localize_property('identity.identified.verifier') - self.assertEqual(self.identity_popup.view.security.verifier.get_property('textContent'), - verifier_label.replace("%S", cert['issuerOrganization'])) - - def opener(mn): - self.identity_popup.view.security.more_info_button.click() - - page_info_window = self.browser.open_page_info_window(opener) - deck = page_info_window.deck - - self.assertEqual(deck.selected_panel, deck.security) - - self.assertEqual(deck.security.domain.get_property('value'), - cert['commonName']) - - self.assertEqual(deck.security.owner.get_property('value'), - page_info_window.localize_property('securityNoOwner')) - - self.assertEqual(deck.security.verifier.get_property('value'), - cert['issuerOrganization']) diff --git a/testing/firefox-ui/tests/functional/security/test_enable_privilege.py b/testing/firefox-ui/tests/functional/security/test_enable_privilege.py deleted file mode 100644 index 17e883cc54..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_enable_privilege.py +++ /dev/null @@ -1,17 +0,0 @@ -# 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/. - -from marionette_driver import By -from marionette_harness import MarionetteTestCase - - -class TestEnablePrivilege(MarionetteTestCase): - - def test_enable_privilege(self): - with self.marionette.using_context('content'): - url = self.marionette.absolute_url('security/enable_privilege.html') - self.marionette.navigate(url) - - result = self.marionette.find_element(By.ID, 'result') - self.assertEqual(result.get_property('textContent'), 'PASS') diff --git a/testing/firefox-ui/tests/functional/security/test_ev_certificate.py b/testing/firefox-ui/tests/functional/security/test_ev_certificate.py deleted file mode 100644 index f5acf57957..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_ev_certificate.py +++ /dev/null @@ -1,112 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestEVCertificate(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestEVCertificate, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - self.url = 'https://ssl-ev.mozqa.com/' - - def tearDown(self): - try: - self.browser.switch_to() - self.identity_popup.close(force=True) - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestEVCertificate, self).tearDown() - - def test_ev_certificate(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - # Check the identity box - self.assertEqual(self.locationbar.identity_box.get_property('className'), - 'verifiedIdentity') - - # Get the information from the certificate - cert = self.browser.tabbar.selected_tab.certificate - address = self.puppeteer.security.get_address_from_certificate(cert) - - # Check the identity popup label displays - self.assertEqual(self.locationbar.identity_organization_label.get_property('value'), - cert['organization']) - self.assertEqual(self.locationbar.identity_country_label.get_property('value'), - '(' + address['country'] + ')') - - # Open the identity popup - self.locationbar.open_identity_popup() - - # Check the idenity popup doorhanger - self.assertEqual(self.identity_popup.element.get_attribute('connection'), 'secure-ev') - - # For EV certificates no hostname but the organization name is shown - self.assertEqual(self.identity_popup.view.main.host.get_property('textContent'), - cert['organization']) - - # Only the secure label is visible in the main view - secure_label = self.identity_popup.view.main.secure_connection_label - self.assertNotEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.main.insecure_connection_label - self.assertEqual(insecure_label.value_of_css_property('display'), 'none') - - self.identity_popup.view.main.expander.click() - Wait(self.marionette).until(lambda _: self.identity_popup.view.security.selected) - - security_view = self.identity_popup.view.security - - # Only the secure label is visible in the security view - secure_label = security_view.secure_connection_label - self.assertNotEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = security_view.insecure_connection_label - self.assertEqual(insecure_label.value_of_css_property('display'), 'none') - - # Check the organization name - self.assertEqual(security_view.owner.get_property('textContent'), cert['organization']) - - # Check the owner location string - # More information: - # hg.mozilla.org/mozilla-central/file/eab4a81e4457/browser/base/content/browser.js#l7012 - location = self.browser.localize_property('identity.identified.state_and_country') - location = location.replace('%S', address['state'], 1).replace('%S', address['country']) - location = address['city'] + '\n' + location - self.assertEqual(security_view.owner_location.get_property('textContent'), location) - - # Check the verifier - l10n_verifier = self.browser.localize_property('identity.identified.verifier') - l10n_verifier = l10n_verifier.replace('%S', cert['issuerOrganization']) - self.assertEqual(security_view.verifier.get_property('textContent'), l10n_verifier) - - # Open the Page Info window by clicking the More Information button - page_info = self.browser.open_page_info_window( - lambda _: self.identity_popup.view.security.more_info_button.click()) - - try: - # Verify that the current panel is the security panel - self.assertEqual(page_info.deck.selected_panel, page_info.deck.security) - - # Verify the domain listed on the security panel - self.assertIn(cert['commonName'], - page_info.deck.security.domain.get_property('value')) - - # Verify the owner listed on the security panel - self.assertEqual(page_info.deck.security.owner.get_property('value'), - cert['organization']) - - # Verify the verifier listed on the security panel - self.assertEqual(page_info.deck.security.verifier.get_property('value'), - cert['issuerOrganization']) - finally: - page_info.close() - self.browser.focus() diff --git a/testing/firefox-ui/tests/functional/security/test_mixed_content_page.py b/testing/firefox-ui/tests/functional/security/test_mixed_content_page.py deleted file mode 100644 index c146b46f4f..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_mixed_content_page.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_harness import MarionetteTestCase - - -class TestMixedContentPage(PuppeteerMixin, MarionetteTestCase): - def setUp(self): - super(TestMixedContentPage, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - self.url = 'https://mozqa.com/data/firefox/security/mixedcontent.html' - - def tearDown(self): - try: - self.identity_popup.close(force=True) - finally: - super(TestMixedContentPage, self).tearDown() - - def test_mixed_content(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.assertEqual(self.locationbar.identity_box.get_property('className'), - 'unknownIdentity mixedDisplayContent') - - # Open the identity popup - self.locationbar.open_identity_popup() - - # Only the insecure label is visible in the main view - secure_label = self.identity_popup.view.main.secure_connection_label - self.assertEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.main.insecure_connection_label - self.assertNotEqual(insecure_label.value_of_css_property('display'), 'none') - - # TODO: Bug 1177417 - Needs to open and close the security view, but a second - # click on the expander doesn't hide the security view - # self.identity_popup.view.main.expander.click() - # Wait(self.marionette).until(lambda _: self.identity_popup.view.security.selected) - - # Only the insecure label is visible in the security view - secure_label = self.identity_popup.view.security.secure_connection_label - self.assertEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.security.insecure_connection_label - self.assertNotEqual(insecure_label.value_of_css_property('display'), 'none') - - # owner is not visible - owner = self.identity_popup.view.security.owner - self.assertEqual(owner.value_of_css_property('display'), 'none') diff --git a/testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py b/testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py deleted file mode 100644 index 796b1dc293..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_mixed_script_content_blocking.py +++ /dev/null @@ -1,87 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, Wait -from marionette_harness import MarionetteTestCase - - -class TestMixedScriptContentBlocking(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestMixedScriptContentBlocking, self).setUp() - - self.url = 'https://mozqa.com/data/firefox/security/mixed_content_blocked/index.html' - - self.test_elements = [ - ('result1', 'Insecure script one'), - ('result2', 'Insecure script from iFrame'), - ('result3', 'Insecure plugin'), - ('result4', 'Insecure stylesheet'), - ] - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - def tearDown(self): - try: - self.identity_popup.close(force=True) - finally: - super(TestMixedScriptContentBlocking, self).tearDown() - - def _expect_protection_status(self, enabled): - if enabled: - color, identity, state = ( - 'rgb(0, 136, 0)', - 'verifiedDomain mixedActiveBlocked', - 'blocked' - ) - else: - color, identity, state = ( - 'rgb(255, 0, 0)', - 'unknownIdentity mixedActiveContent', - 'unblocked' - ) - - # First call to Wait() needs a longer timeout due to the reload of the web page. - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda _: self.locationbar.identity_box.get_property('className') == identity, - message='Expected identity "{}" not found'.format(identity) - ) - - with self.marionette.using_context('content'): - for identifier, description in self.test_elements: - el = self.marionette.find_element(By.ID, identifier) - Wait(self.marionette).until( - lambda mn: el.value_of_css_property('color') == color, - message=("%s has been %s" % (description, state)) - ) - - def expect_protection_enabled(self): - self._expect_protection_status(True) - - def expect_protection_disabled(self): - self._expect_protection_status(False) - - def test_mixed_content_page(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.expect_protection_enabled() - - # Disable mixed content blocking via identity popup - self.locationbar.open_identity_popup() - self.identity_popup.view.main.expander.click() - Wait(self.marionette).until(lambda _: self.identity_popup.view.security.selected) - - disable_button = self.identity_popup.view.security.disable_mixed_content_blocking_button - disable_button.click() - - self.expect_protection_disabled() - - # A reload keeps blocking disabled - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.expect_protection_disabled() diff --git a/testing/firefox-ui/tests/functional/security/test_no_certificate.py b/testing/firefox-ui/tests/functional/security/test_no_certificate.py deleted file mode 100644 index a3b7bf98a0..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_no_certificate.py +++ /dev/null @@ -1,81 +0,0 @@ -# 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/. - -from urlparse import urlparse - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import expected, Wait -from marionette_harness import MarionetteTestCase - - -class TestNoCertificate(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestNoCertificate, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - self.url = self.marionette.absolute_url('layout/mozilla.html') - - def tearDown(self): - try: - self.browser.switch_to() - self.identity_popup.close(force=True) - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestNoCertificate, self).tearDown() - - def test_no_certificate(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - # Check the favicon - # TODO: find a better way to check, e.g., mozmill's isDisplayed - favicon_hidden = self.marionette.execute_script(""" - return arguments[0].hasAttribute("hidden"); - """, script_args=[self.browser.navbar.locationbar.identity_icon]) - self.assertFalse(favicon_hidden, 'The identity icon is visible') - - # Check that the identity box organization label is blank - self.assertEqual(self.locationbar.identity_organization_label.get_property('value'), '', - 'The organization has no label') - - # Open the identity popup - self.locationbar.open_identity_popup() - - # Check the idenity popup doorhanger - self.assertEqual(self.identity_popup.element.get_attribute('connection'), 'not-secure') - - # The expander for the security view does not exist - expected.element_not_present(lambda m: self.identity_popup.main.expander) - - # Only the insecure label is visible - secure_label = self.identity_popup.view.main.secure_connection_label - self.assertEqual(secure_label.value_of_css_property('display'), 'none') - - insecure_label = self.identity_popup.view.main.insecure_connection_label - self.assertNotEqual(insecure_label.value_of_css_property('display'), 'none') - - self.identity_popup.view.main.expander.click() - Wait(self.marionette).until(lambda _: self.identity_popup.view.security.selected) - - # Open the Page Info window by clicking the "More Information" button - page_info = self.browser.open_page_info_window( - lambda _: self.identity_popup.view.security.more_info_button.click()) - - # Verify that the current panel is the security panel - self.assertEqual(page_info.deck.selected_panel, page_info.deck.security) - - # Check the domain listed on the security panel contains the url's host name - self.assertIn(urlparse(self.url).hostname, - page_info.deck.security.domain.get_property('value')) - - # Check the owner label equals localized 'securityNoOwner' - self.assertEqual(page_info.deck.security.owner.get_property('value'), - page_info.localize_property('securityNoOwner')) - - # Check the verifier label equals localized 'notset' - self.assertEqual(page_info.deck.security.verifier.get_property('value'), - page_info.localize_property('notset')) diff --git a/testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py b/testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py deleted file mode 100644 index 6f9c50ffbc..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_initial_download.py +++ /dev/null @@ -1,84 +0,0 @@ -# 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 - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase - - -class TestSafeBrowsingInitialDownload(PuppeteerMixin, MarionetteTestCase): - - file_extensions = [ - 'pset', - 'sbstore', - ] - - prefs_download_lists = [ - 'urlclassifier.blockedTable', - 'urlclassifier.downloadAllowTable', - 'urlclassifier.downloadBlockTable', - 'urlclassifier.malwareTable', - 'urlclassifier.phishTable', - 'urlclassifier.trackingTable', - 'urlclassifier.trackingWhitelistTable', - ] - - prefs_provider_update_time = { - # Force an immediate download of the safebrowsing files - 'browser.safebrowsing.provider.google.nextupdatetime': 1, - 'browser.safebrowsing.provider.mozilla.nextupdatetime': 1, - } - - prefs_safebrowsing = { - 'browser.safebrowsing.debug': True, - 'browser.safebrowsing.blockedURIs.enabled': True, - 'browser.safebrowsing.downloads.enabled': True, - 'browser.safebrowsing.phishing.enabled': True, - 'browser.safebrowsing.malware.enabled': True, - 'privacy.trackingprotection.enabled': True, - 'privacy.trackingprotection.pbmode.enabled': True, - } - - def get_safebrowsing_files(self): - files = [] - for pref_name in self.prefs_download_lists: - base_names = self.marionette.get_pref(pref_name).split(',') - for ext in self.file_extensions: - files.extend(['{file}.{ext}'.format(file=f, ext=ext) for f in base_names if f]) - - return set(sorted(files)) - - def setUp(self): - super(TestSafeBrowsingInitialDownload, self).setUp() - - # Force the preferences for the new profile - enforce_prefs = self.prefs_safebrowsing - enforce_prefs.update(self.prefs_provider_update_time) - self.marionette.enforce_gecko_prefs(enforce_prefs) - - self.safebrowsing_path = os.path.join(self.marionette.instance.profile.profile, - 'safebrowsing') - self.safebrowsing_files = self.get_safebrowsing_files() - - def tearDown(self): - try: - # Restart with a fresh profile - self.restart(clean=True) - finally: - super(TestSafeBrowsingInitialDownload, self).tearDown() - - def test_safe_browsing_initial_download(self): - def check_downloaded(_): - return reduce(lambda state, pref: state and int(self.marionette.get_pref(pref)) != 1, - self.prefs_provider_update_time.keys(), True) - - try: - Wait(self.marionette, timeout=60).until( - check_downloaded, message='Not all safebrowsing files have been downloaded') - finally: - files_on_disk_toplevel = os.listdir(self.safebrowsing_path) - for f in self.safebrowsing_files: - self.assertIn(f, files_on_disk_toplevel) diff --git a/testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py b/testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py deleted file mode 100644 index 5fb3d03892..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_notification.py +++ /dev/null @@ -1,149 +0,0 @@ -# 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 time - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, expected, Wait -from marionette_harness import MarionetteTestCase - - -class TestSafeBrowsingNotificationBar(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSafeBrowsingNotificationBar, self).setUp() - - self.test_data = [ - # Unwanted software URL - { - # First two properties are not needed, - # since these errors are not reported - 'button_property': None, - 'report_page': None, - 'unsafe_page': 'https://www.itisatrap.org/firefox/unwanted.html' - }, - # Phishing URL info - { - 'button_property': 'safebrowsing.notADeceptiveSiteButton.label', - 'report_page': 'google.com/safebrowsing/report_error', - 'unsafe_page': 'https://www.itisatrap.org/firefox/its-a-trap.html' - }, - # Malware URL object - { - 'button_property': 'safebrowsing.notAnAttackButton.label', - 'report_page': 'stopbadware.org', - 'unsafe_page': 'https://www.itisatrap.org/firefox/its-an-attack.html' - } - ] - - self.marionette.set_pref('browser.safebrowsing.phishing.enabled', True) - self.marionette.set_pref('browser.safebrowsing.malware.enabled', True) - - # Give the browser a little time, because SafeBrowsing.jsm takes a while - # between start up and adding the example urls to the db. - # hg.mozilla.org/mozilla-central/file/46aebcd9481e/browser/base/content/browser.js#l1194 - time.sleep(3) - - # TODO: Bug 1139544: While we don't have a reliable way to close the safe browsing - # notification bar when a test fails, run this test in a new tab. - self.browser.tabbar.open_tab() - - def tearDown(self): - try: - self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing') - self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]]) - self.marionette.clear_pref('browser.safebrowsing.phishing.enabled') - self.marionette.clear_pref('browser.safebrowsing.malware.enabled') - finally: - super(TestSafeBrowsingNotificationBar, self).tearDown() - - def test_notification_bar(self): - with self.marionette.using_context('content'): - for item in self.test_data: - button_property = item['button_property'] - report_page, unsafe_page = item['report_page'], item['unsafe_page'] - - # Navigate to the unsafe page - # Check "ignore warning" link then notification bar's "not badware" button - # Only do this if feature supports it - if button_property is not None: - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_ignore_warning_button(unsafe_page) - self.check_not_badware_button(button_property, report_page) - - # Return to the unsafe page - # Check "ignore warning" link then notification bar's "get me out" button - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_ignore_warning_button(unsafe_page) - self.check_get_me_out_of_here_button() - - # Return to the unsafe page - # Check "ignore warning" link then notification bar's "X" button - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_ignore_warning_button(unsafe_page) - self.check_x_button() - - def check_ignore_warning_button(self, unsafe_page): - button = self.marionette.find_element(By.ID, 'ignoreWarningButton') - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - expected.element_present(By.ID, 'main-feature'), - message='Expected target element "#main-feature" has not been found', - ) - self.assertEquals(self.marionette.get_url(), self.browser.get_final_url(unsafe_page)) - - # Clean up here since the permission gets set in this function - self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing') - - # Check the not a forgery or attack button in the notification bar - def check_not_badware_button(self, button_property, report_page): - with self.marionette.using_context('chrome'): - # TODO: update to use safe browsing notification bar class when bug 1139544 lands - label = self.browser.localize_property(button_property) - button = (self.marionette.find_element(By.ID, 'content') - .find_element('anon attribute', {'label': label})) - - self.browser.tabbar.open_tab(lambda _: button.click()) - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: report_page in mn.get_url(), - message='The expected safe-browsing report page has not been opened', - ) - - with self.marionette.using_context('chrome'): - self.browser.tabbar.close_tab() - - def check_get_me_out_of_here_button(self): - with self.marionette.using_context('chrome'): - # TODO: update to use safe browsing notification bar class when bug 1139544 lands - label = self.browser.localize_property('safebrowsing.getMeOutOfHereButton.label') - button = (self.marionette.find_element(By.ID, 'content') - .find_element('anon attribute', {'label': label})) - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: self.browser.default_homepage in mn.get_url(), - message='The default home page has not been loaded', - ) - - def check_x_button(self): - with self.marionette.using_context('chrome'): - # TODO: update to use safe browsing notification bar class when bug 1139544 lands - button = (self.marionette.find_element(By.ID, 'content') - .find_element('anon attribute', {'value': 'blocked-badware-page'}) - .find_element('anon attribute', - {'class': 'messageCloseButton close-icon tabbable'})) - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - expected.element_stale(button), - message='The notification bar has not been closed', - ) diff --git a/testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py b/testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py deleted file mode 100644 index 968a9464b1..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_safe_browsing_warning_pages.py +++ /dev/null @@ -1,115 +0,0 @@ -# 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 time - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, expected, Wait -from marionette_harness import MarionetteTestCase - - -class TestSafeBrowsingWarningPages(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSafeBrowsingWarningPages, self).setUp() - - self.urls = [ - # Unwanted software URL - 'https://www.itisatrap.org/firefox/unwanted.html', - # Phishing URL - 'https://www.itisatrap.org/firefox/its-a-trap.html', - # Malware URL - 'https://www.itisatrap.org/firefox/its-an-attack.html' - ] - - self.marionette.set_pref('app.support.baseURL', - self.marionette.absolute_url("support.html?topic=")) - self.marionette.set_pref('browser.safebrowsing.phishing.enabled', True) - self.marionette.set_pref('browser.safebrowsing.malware.enabled', True) - - # Give the browser a little time, because SafeBrowsing.jsm takes a - # while between start up and adding the example urls to the db. - # hg.mozilla.org/mozilla-central/file/46aebcd9481e/browser/base/content/browser.js#l1194 - time.sleep(3) - - # TODO: Bug 1139544: While we don't have a reliable way to close the safe browsing - # notification bar when a test fails, run this test in a new tab. - self.browser.tabbar.open_tab() - - def tearDown(self): - try: - self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing') - self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]]) - self.marionette.clear_pref('app.support.baseURL') - self.marionette.clear_pref('browser.safebrowsing.malware.enabled') - self.marionette.clear_pref('browser.safebrowsing.phishing.enabled') - finally: - super(TestSafeBrowsingWarningPages, self).tearDown() - - def test_warning_pages(self): - with self.marionette.using_context("content"): - for unsafe_page in self.urls: - # Load a test page, then test the get me out button - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_get_me_out_of_here_button(unsafe_page) - - # Load the test page again, then test the report button - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_report_button(unsafe_page) - - # Load the test page again, then test the ignore warning button - self.marionette.navigate(unsafe_page) - # Wait for the DOM to receive events for about:blocked - time.sleep(1) - self.check_ignore_warning_button(unsafe_page) - - def check_get_me_out_of_here_button(self, unsafe_page): - button = self.marionette.find_element(By.ID, "getMeOutButton") - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: self.browser.default_homepage in mn.get_url()) - - def check_report_button(self, unsafe_page): - # Get the URL of the support site for phishing and malware. This may result in a redirect. - with self.marionette.using_context('chrome'): - url = self.marionette.execute_script(""" - Components.utils.import("resource://gre/modules/Services.jsm"); - return Services.urlFormatter.formatURLPref("app.support.baseURL") - + "phishing-malware"; - """) - - button = self.marionette.find_element(By.ID, "reportButton") - button.click() - - # Wait for the button to become stale, whereby a longer timeout is needed - # here to not fail in case of slow connections. - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - expected.element_stale(button)) - - # Wait for page load to be completed, so we can verify the URL even if a redirect happens. - # TODO: Bug 1140470: use replacement for mozmill's waitforPageLoad - expected_url = self.browser.get_final_url(url) - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: expected_url == mn.get_url(), - message="The expected URL '{}' has not been loaded".format(expected_url) - ) - - topic = self.marionette.find_element(By.ID, "topic") - self.assertEquals(topic.text, "phishing-malware") - - def check_ignore_warning_button(self, unsafe_page): - button = self.marionette.find_element(By.ID, 'ignoreWarningButton') - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - expected.element_present(By.ID, 'main-feature')) - self.assertEquals(self.marionette.get_url(), self.browser.get_final_url(unsafe_page)) - - # Clean up by removing safe browsing permission for unsafe page - self.puppeteer.utils.permissions.remove('https://www.itisatrap.org', 'safe-browsing') diff --git a/testing/firefox-ui/tests/functional/security/test_security_notification.py b/testing/firefox-ui/tests/functional/security/test_security_notification.py deleted file mode 100644 index 5825d03648..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_security_notification.py +++ /dev/null @@ -1,62 +0,0 @@ -# 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 time - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, Wait -from marionette_driver.errors import MarionetteException -from marionette_harness import MarionetteTestCase - - -class TestSecurityNotification(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSecurityNotification, self).setUp() - - self.urls = [ - # Invalid cert page - 'https://ssl-expired.mozqa.com', - # Secure page - 'https://ssl-ev.mozqa.com/', - # Insecure page - 'http://no-ssl.mozqa.com' - ] - - self.identity_box = self.browser.navbar.locationbar.identity_box - - def test_invalid_cert(self): - with self.marionette.using_context('content'): - # Go to a site that has an invalid (expired) cert - self.assertRaises(MarionetteException, self.marionette.navigate, self.urls[0]) - - # Wait for the DOM to receive events - time.sleep(1) - - # Verify the text in Technical Content contains the page with invalid cert - text = self.marionette.find_element(By.ID, 'badCertTechnicalInfo') - self.assertIn(self.urls[0][8:], text.get_property('textContent')) - - # Verify the "Go Back" and "Advanced" buttons appear - self.assertIsNotNone(self.marionette.find_element(By.ID, 'returnButton')) - self.assertIsNotNone(self.marionette.find_element(By.ID, 'advancedButton')) - - # Verify the error code is correct - self.assertIn('SEC_ERROR_EXPIRED_CERTIFICATE', text.get_property('textContent')) - - def test_secure_website(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.urls[1]) - - Wait(self.marionette).until(lambda _: ( - self.identity_box.get_property('className') == 'verifiedIdentity') - ) - - def test_insecure_website(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.urls[2]) - - Wait(self.marionette).until(lambda _: ( - self.identity_box.get_property('className') == 'unknownIdentity') - ) diff --git a/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py b/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py deleted file mode 100644 index d1d9c531f3..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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 time - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, expected, Wait -from marionette_driver.errors import MarionetteException -from marionette_harness import MarionetteTestCase - - -class TestSSLDisabledErrorPage(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSSLDisabledErrorPage, self).setUp() - - self.url = 'https://tlsv1-0.mozqa.com' - - self.puppeteer.utils.sanitize({"sessions": True}) - - # Disable SSL 3.0, TLS 1.0 and TLS 1.1 for secure connections - # by forcing the use of TLS 1.2 - # see: http://kb.mozillazine.org/Security.tls.version.*#Possible_values_and_their_effects - self.marionette.set_pref('security.tls.version.min', 3) - self.marionette.set_pref('security.tls.version.max', 3) - - def tearDown(self): - try: - self.marionette.clear_pref('security.tls.version.min') - self.marionette.clear_pref('security.tls.version.max') - finally: - super(TestSSLDisabledErrorPage, self).tearDown() - - def test_ssl_disabled_error_page(self): - with self.marionette.using_context('content'): - # Open the test page - self.assertRaises(MarionetteException, self.marionette.navigate, self.url) - - # Wait for the DOM to receive events - time.sleep(1) - - # Verify "Secure Connection Failed" error page title - title = self.marionette.find_element(By.CLASS_NAME, 'title-text') - nss_failure2title = self.browser.localize_entity('nssFailure2.title') - self.assertEquals(title.get_property('textContent'), nss_failure2title) - - # Verify the error message is correct - short_description = self.marionette.find_element(By.ID, 'errorShortDescText') - self.assertIn('SSL_ERROR_UNSUPPORTED_VERSION', - short_description.get_property('textContent')) - self.assertIn('mozqa.com', short_description.get_property('textContent')) - - # Verify that the "Restore" button appears and works - reset_button = self.marionette.find_element(By.ID, 'prefResetButton') - reset_button.click() - - # With the preferences reset, the page has to load correctly - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - expected.element_present(By.LINK_TEXT, 'http://quality.mozilla.org')) diff --git a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py deleted file mode 100644 index f274d8f2fd..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py +++ /dev/null @@ -1,124 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import Wait -from marionette_harness import MarionetteTestCase, skip_if_e10s - - -class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSSLStatusAfterRestart, self).setUp() - - self.test_data = ( - { - 'url': 'https://ssl-dv.mozqa.com', - 'identity': '', - 'type': 'secure' - }, - { - 'url': 'https://ssl-ev.mozqa.com/', - 'identity': 'Mozilla Corporation', - 'type': 'secure-ev' - }, - { - 'url': 'https://ssl-ov.mozqa.com/', - 'identity': '', - 'type': 'secure' - } - ) - - # Set browser to restore previous session - self.marionette.set_pref('browser.startup.page', 3) - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]]) - self.browser.switch_to() - self.identity_popup.close(force=True) - self.marionette.clear_pref('browser.startup.page') - finally: - super(TestSSLStatusAfterRestart, self).tearDown() - - @skip_if_e10s("Bug 1325047") - def test_ssl_status_after_restart(self): - for item in self.test_data: - with self.marionette.using_context('content'): - self.marionette.navigate(item['url']) - self.verify_certificate_status(item) - self.browser.tabbar.open_tab() - - self.restart() - - # Refresh references to elements - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - for index, item in enumerate(self.test_data): - self.browser.tabbar.tabs[index].select() - self.verify_certificate_status(item) - - def verify_certificate_status(self, item): - url, identity, cert_type = item['url'], item['identity'], item['type'] - - # Check the favicon - # TODO: find a better way to check, e.g., mozmill's isDisplayed - favicon_hidden = self.marionette.execute_script(""" - return arguments[0].hasAttribute("hidden"); - """, script_args=[self.browser.navbar.locationbar.identity_icon]) - self.assertFalse(favicon_hidden) - - self.locationbar.open_identity_popup() - - # Check the type shown on the identity popup doorhanger - self.assertEqual(self.identity_popup.element.get_attribute('connection'), - cert_type) - - self.identity_popup.view.main.expander.click() - Wait(self.marionette).until(lambda _: self.identity_popup.view.security.selected) - - # Check the identity label - self.assertEqual(self.locationbar.identity_organization_label.get_property('value'), - identity) - - # Get the information from the certificate - cert = self.browser.tabbar.selected_tab.certificate - - # Open the Page Info window by clicking the More Information button - page_info = self.browser.open_page_info_window( - lambda _: self.identity_popup.view.security.more_info_button.click()) - - # Verify that the current panel is the security panel - self.assertEqual(page_info.deck.selected_panel, page_info.deck.security) - - # Verify the domain listed on the security panel - # If this is a wildcard cert, check only the domain - if cert['commonName'].startswith('*'): - self.assertIn(self.puppeteer.security.get_domain_from_common_name(cert['commonName']), - page_info.deck.security.domain.get_property('value'), - 'Expected domain found in certificate for ' + url) - else: - self.assertEqual(page_info.deck.security.domain.get_property('value'), - cert['commonName'], - 'Domain value matches certificate common name.') - - # Verify the owner listed on the security panel - if identity != '': - owner = cert['organization'] - else: - owner = page_info.localize_property('securityNoOwner') - - self.assertEqual(page_info.deck.security.owner.get_property('value'), owner, - 'Expected owner label found for ' + url) - - # Verify the verifier listed on the security panel - self.assertEqual(page_info.deck.security.verifier.get_property('value'), - cert['issuerOrganization'], - 'Verifier matches issuer of certificate for ' + url) - page_info.close() diff --git a/testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py b/testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py deleted file mode 100644 index a2f431fb52..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_submit_unencrypted_info_warning.py +++ /dev/null @@ -1,65 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, expected, Wait -from marionette_driver.errors import NoAlertPresentException -from marionette_driver.marionette import Alert -from marionette_harness import MarionetteTestCase - - -class TestSubmitUnencryptedInfoWarning(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSubmitUnencryptedInfoWarning, self).setUp() - - self.url = 'https://ssl-dv.mozqa.com/data/firefox/security/unencryptedsearch.html' - self.test_string = 'mozilla' - - self.marionette.set_pref('security.warn_submit_insecure', True) - - def tearDown(self): - try: - self.marionette.clear_pref('security.warn_submit_insecure') - finally: - super(TestSubmitUnencryptedInfoWarning, self).tearDown() - - def test_submit_unencrypted_info_warning(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - # Get the page's search box and submit button. - searchbox = self.marionette.find_element(By.ID, 'q') - button = self.marionette.find_element(By.ID, 'submit') - - # Use the page's search box to submit information. - searchbox.send_keys(self.test_string) - button.click() - - # Get the expected warning text and replace its two instances of "##" with "\n\n". - message = self.browser.localize_property('formPostSecureToInsecureWarning.message') - message = message.replace('##', '\n\n') - - # Wait for the warning, verify the expected text matches warning, accept the warning - warning = Alert(self.marionette) - try: - Wait(self.marionette, - ignored_exceptions=NoAlertPresentException, - timeout=self.marionette.timeout.page_load).until( - lambda _: warning.text == message) - finally: - warning.accept() - - # Wait for the search box to become stale, then wait for the page to be reloaded. - Wait(self.marionette).until(expected.element_stale(searchbox)) - - # TODO: Bug 1140470: use replacement for mozmill's waitforPageLoad - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: mn.execute_script('return document.readyState == "DOMContentLoaded" ||' - ' document.readyState == "complete";') - ) - - # Check that search_term contains the test string. - search_term = self.marionette.find_element(By.ID, 'search-term') - self.assertEqual(search_term.get_property('textContent'), self.test_string) diff --git a/testing/firefox-ui/tests/functional/security/test_unknown_issuer.py b/testing/firefox-ui/tests/functional/security/test_unknown_issuer.py deleted file mode 100644 index b329f25005..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_unknown_issuer.py +++ /dev/null @@ -1,34 +0,0 @@ -# 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 time - -from marionette_driver import By -from marionette_driver.errors import MarionetteException -from marionette_harness import MarionetteTestCase - - -class TestUnknownIssuer(MarionetteTestCase): - - def setUp(self): - super(TestUnknownIssuer, self).setUp() - - self.url = 'https://ssl-unknownissuer.mozqa.com' - - def test_unknown_issuer(self): - with self.marionette.using_context('content'): - # Go to a site that has a cert with an unknown issuer - self.assertRaises(MarionetteException, self.marionette.navigate, self.url) - - # Wait for the DOM to receive events - time.sleep(1) - - # Check for the correct error code - error = self.marionette.find_element(By.ID, 'errorCode') - self.assertEquals(error.get_property('textContent'), - 'SEC_ERROR_UNKNOWN_ISSUER') - - # Verify the "Go Back" and "Advanced" buttons appear - self.assertIsNotNone(self.marionette.find_element(By.ID, 'returnButton')) - self.assertIsNotNone(self.marionette.find_element(By.ID, 'advancedButton')) diff --git a/testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py b/testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py deleted file mode 100644 index 0dbce1c8fc..0000000000 --- a/testing/firefox-ui/tests/functional/security/test_untrusted_connection_error_page.py +++ /dev/null @@ -1,35 +0,0 @@ -# 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 time - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, Wait -from marionette_driver.errors import MarionetteException -from marionette_harness import MarionetteTestCase - - -class TestUntrustedConnectionErrorPage(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestUntrustedConnectionErrorPage, self).setUp() - - self.url = 'https://ssl-selfsigned.mozqa.com' - - def test_untrusted_connection_error_page(self): - self.marionette.set_context('content') - - # In some localized builds, the default page redirects - target_url = self.browser.get_final_url(self.browser.default_homepage) - - self.assertRaises(MarionetteException, self.marionette.navigate, self.url) - - # Wait for the DOM to receive events - time.sleep(1) - - button = self.marionette.find_element(By.ID, "returnButton") - button.click() - - Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( - lambda mn: target_url == self.marionette.get_url()) diff --git a/testing/firefox-ui/tests/functional/sessionstore/manifest.ini b/testing/firefox-ui/tests/functional/sessionstore/manifest.ini deleted file mode 100644 index c2d0a02b8b..0000000000 --- a/testing/firefox-ui/tests/functional/sessionstore/manifest.ini +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -tags = local - -[test_restore_windows_after_restart.py] -skip-if = (os == "win" || e10s) # Bug 1291844 and Bug 1228446 diff --git a/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py b/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py deleted file mode 100644 index cc7de728bb..0000000000 --- a/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_restart.py +++ /dev/null @@ -1,150 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_harness import MarionetteTestCase - - -class TestRestoreWindowsAfterRestart(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestRestoreWindowsAfterRestart, self).setUp() - - # Each list element represents a window of tabs loaded at - # some testing URL - self.test_windows = set([ - # Window 1. Note the comma after the absolute_url call - - # this is Python's way of declaring a 1 item tuple. - (self.marionette.absolute_url('layout/mozilla.html'), ), - - # Window 2 - (self.marionette.absolute_url('layout/mozilla_organizations.html'), - self.marionette.absolute_url('layout/mozilla_community.html')), - - # Window 3 - (self.marionette.absolute_url('layout/mozilla_governance.html'), - self.marionette.absolute_url('layout/mozilla_grants.html')), - ]) - - self.private_windows = set([ - (self.marionette.absolute_url('layout/mozilla_mission.html'), - self.marionette.absolute_url('layout/mozilla_organizations.html')), - - (self.marionette.absolute_url('layout/mozilla_projects.html'), - self.marionette.absolute_url('layout/mozilla_mission.html')), - ]) - - self.marionette.enforce_gecko_prefs({ - # Set browser to restore previous session - 'browser.startup.page': 3, - # Make the content load right away instead of waiting for - # the user to click on the background tabs - 'browser.sessionstore.restore_on_demand': False, - # Avoid race conditions by having the content process never - # send us session updates unless the parent has explicitly asked - # for them via the TabStateFlusher. - 'browser.sessionstore.debug.no_auto_updates': True, - }) - - def tearDown(self): - try: - # Create a fresh profile for subsequent tests. - self.restart(clean=True) - finally: - super(TestRestoreWindowsAfterRestart, self).tearDown() - - def test_with_variety(self): - """ Opens a set of windows, both standard and private, with - some number of tabs in them. Once the tabs have loaded, restarts - the browser, and then ensures that the standard tabs have been - restored, and that the private ones have not. - """ - self.open_windows(self.test_windows) - self.open_windows(self.private_windows, is_private=True) - - self.restart() - - windows = self.puppeteer.windows.all - - # There's no guarantee that Marionette will return us an - # iterator for the opened windows that will match the - # order within our window list. Instead, we'll convert - # the list of URLs within each open window to a set of - # tuples that will allow us to do a direct comparison - # while allowing the windows to be in any order. - opened_windows = set() - for win in windows: - urls = tuple() - for tab in win.tabbar.tabs: - urls = urls + tuple([tab.location]) - opened_windows.add(urls) - - self.assertEqual(opened_windows, self.test_windows) - - def open_windows(self, window_sets, is_private=False): - """ Opens a set of windows with tabs pointing at some - URLs. - - @param window_sets (list) - A set of URL tuples. Each tuple within window_sets - represents a window, and each URL in the URL - tuples represents what will be loaded in a tab. - - Note that if is_private is False, then the first - URL tuple will be opened in the current window, and - subequent tuples will be opened in new windows. - - Example: - - set( - (self.marionette.absolute_url('layout/mozilla_1.html'), - self.marionette.absolute_url('layout/mozilla_2.html')), - - (self.marionette.absolute_url('layout/mozilla_3.html'), - self.marionette.absolute_url('layout/mozilla_4.html')), - ) - - This would take the currently open window, and load - mozilla_1.html and mozilla_2.html in new tabs. It would - then open a new, second window, and load tabs at - mozilla_3.html and mozilla_4.html. - @param is_private (boolean, optional) - Whether or not any new windows should be a private browsing - windows. - """ - - if (is_private): - win = self.browser.open_browser(is_private=True) - win.switch_to() - else: - win = self.browser - - for index, urls in enumerate(window_sets): - if index > 0: - win = self.browser.open_browser(is_private=is_private) - win.switch_to() - self.open_tabs(win, urls) - - def open_tabs(self, win, urls): - """ Opens a set of URLs inside a window in new tabs. - - @param win (browser window) - The browser window to load the tabs in. - @param urls (tuple) - A tuple of URLs to load in this window. The - first URL will be loaded in the currently selected - browser tab. Subsequent URLs will be loaded in - new tabs. - """ - # If there are any remaining URLs for this window, - # open some new tabs and navigate to them. - with self.marionette.using_context('content'): - if isinstance(urls, str): - self.marionette.navigate(urls) - else: - for index, url in enumerate(urls): - if index > 0: - with self.marionette.using_context('chrome'): - win.tabbar.open_tab() - self.marionette.navigate(url) diff --git a/testing/firefox-ui/tests/puppeteer/manifest.ini b/testing/firefox-ui/tests/puppeteer/manifest.ini deleted file mode 100644 index 2eb24b6dc0..0000000000 --- a/testing/firefox-ui/tests/puppeteer/manifest.ini +++ /dev/null @@ -1,24 +0,0 @@ -[DEFAULT] -tags = local - -# API tests -[test_appinfo.py] -[test_l10n.py] -[test_places.py] -[test_security.py] -tags = remote -[test_software_update.py] -tags = remote -[test_utils.py] - -# UI tests -[test_about_window.py] -[test_menubar.py] -[test_notifications.py] -[test_page_info_window.py] -[test_tabbar.py] -[test_toolbars.py] -tags = remote -[test_update_wizard.py] -tags = remote -[test_windows.py] diff --git a/testing/firefox-ui/tests/puppeteer/test_about_window.py b/testing/firefox-ui/tests/puppeteer/test_about_window.py deleted file mode 100644 index c957211bb7..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_about_window.py +++ /dev/null @@ -1,74 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.ui.deck import Panel -from marionette_harness import MarionetteTestCase - - -class TestAboutWindow(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestAboutWindow, self).setUp() - - self.about_window = self.browser.open_about_window() - self.deck = self.about_window.deck - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestAboutWindow, self).tearDown() - - def test_basic(self): - self.assertEqual(self.about_window.window_type, 'Browser:About') - - def test_elements(self): - """Test correct retrieval of elements.""" - self.assertNotEqual(self.about_window.dtds, []) - - self.assertEqual(self.deck.element.get_property('localName'), 'deck') - - # apply panel - panel = self.deck.apply - self.assertEqual(panel.element.get_property('localName'), 'hbox') - self.assertEqual(panel.button.get_property('localName'), 'button') - - # check_for_updates panel - panel = self.deck.check_for_updates - self.assertEqual(panel.element.get_property('localName'), 'hbox') - self.assertEqual(panel.button.get_property('localName'), 'button') - - # checking_for_updates panel - self.assertEqual(self.deck.checking_for_updates.element.get_property('localName'), 'hbox') - - # download_and_install panel - panel = self.deck.download_and_install - self.assertEqual(panel.element.get_property('localName'), 'hbox') - self.assertEqual(panel.button.get_property('localName'), 'button') - - # download_failed panel - self.assertEqual(self.deck.download_failed.element.get_property('localName'), 'hbox') - - # downloading panel - self.assertEqual(self.deck.downloading.element.get_property('localName'), 'hbox') - - # check deck attributes - self.assertIsInstance(self.deck.selected_index, int) - self.assertIsInstance(self.deck.selected_panel, Panel) - - def test_open_window(self): - """Test various opening strategies.""" - def opener(win): - self.browser.menubar.select_by_id('helpMenu', 'aboutName') - - open_strategies = ('menu', - opener, - ) - - self.about_window.close() - for trigger in open_strategies: - about_window = self.browser.open_about_window(trigger=trigger) - self.assertEquals(about_window, self.puppeteer.windows.current) - about_window.close() diff --git a/testing/firefox-ui/tests/puppeteer/test_appinfo.py b/testing/firefox-ui/tests/puppeteer/test_appinfo.py deleted file mode 100644 index f0be0f6168..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_appinfo.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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 mozversion - -from firefox_puppeteer import PuppeteerMixin -from marionette_harness import MarionetteTestCase - - -class TestAppInfo(PuppeteerMixin, MarionetteTestCase): - - def test_valid_properties(self): - binary = self.marionette.bin - version_info = mozversion.get_version(binary=binary) - - self.assertEqual(self.puppeteer.appinfo.ID, version_info['application_id']) - self.assertEqual(self.puppeteer.appinfo.name, version_info['application_name']) - self.assertEqual(self.puppeteer.appinfo.vendor, version_info['application_vendor']) - self.assertEqual(self.puppeteer.appinfo.version, version_info['application_version']) - # Bug 1298328 - Platform buildid mismatch due to incremental builds - # self.assertEqual(self.puppeteer.appinfo.platformBuildID, - # version_info['platform_buildid']) - self.assertEqual(self.puppeteer.appinfo.platformVersion, version_info['platform_version']) - self.assertIsNotNone(self.puppeteer.appinfo.locale) - self.assertIsNotNone(self.puppeteer.appinfo.user_agent) - self.assertIsNotNone(self.puppeteer.appinfo.XPCOMABI) - - def test_invalid_properties(self): - with self.assertRaises(AttributeError): - self.puppeteer.appinfo.unknown diff --git a/testing/firefox-ui/tests/puppeteer/test_l10n.py b/testing/firefox-ui/tests/puppeteer/test_l10n.py deleted file mode 100644 index 08f41f9d71..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_l10n.py +++ /dev/null @@ -1,51 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.api.l10n import L10n -from marionette_driver import By -from marionette_driver.errors import NoSuchElementException -from marionette_harness import MarionetteTestCase - - -class TestL10n(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestL10n, self).setUp() - - self.l10n = L10n(self.marionette) - - def test_dtd_entity_chrome(self): - dtds = ['chrome://global/locale/about.dtd', - 'chrome://browser/locale/baseMenuOverlay.dtd'] - - value = self.l10n.localize_entity(dtds, 'helpSafeMode.label') - elm = self.marionette.find_element(By.ID, 'helpSafeMode') - self.assertEqual(value, elm.get_attribute('label')) - - self.assertRaises(NoSuchElementException, - self.l10n.localize_entity, dtds, 'notExistent') - - def test_dtd_entity_content(self): - dtds = ['chrome://global/locale/about.dtd', - 'chrome://global/locale/aboutSupport.dtd'] - - value = self.l10n.localize_entity(dtds, 'aboutSupport.pageTitle') - - self.marionette.set_context(self.marionette.CONTEXT_CONTENT) - self.marionette.navigate('about:support') - - elm = self.marionette.find_element(By.TAG_NAME, 'title') - self.assertEqual(value, elm.text) - - def test_properties(self): - properties = ['chrome://global/locale/filepicker.properties', - 'chrome://global/locale/findbar.properties'] - - # TODO: Find a way to verify the retrieved translated string - value = self.l10n.localize_property(properties, 'NotFound') - self.assertNotEqual(value, '') - - self.assertRaises(NoSuchElementException, - self.l10n.localize_property, properties, 'notExistent') diff --git a/testing/firefox-ui/tests/puppeteer/test_menubar.py b/testing/firefox-ui/tests/puppeteer/test_menubar.py deleted file mode 100644 index ddc6117bf7..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_menubar.py +++ /dev/null @@ -1,30 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver.errors import NoSuchElementException -from marionette_harness import MarionetteTestCase - - -class TestMenuBar(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestMenuBar, self).setUp() - - def test_click_item_in_menubar(self): - def opener(_): - self.browser.menubar.select_by_id('file-menu', - 'menu_newNavigatorTab') - - self.browser.tabbar.open_tab(trigger=opener) - - self.browser.tabbar.tabs[-1].close() - - def test_click_non_existent_menu_and_item(self): - with self.assertRaises(NoSuchElementException): - self.browser.menubar.select_by_id('foobar-menu', - 'menu_newNavigatorTab') - - with self.assertRaises(NoSuchElementException): - self.browser.menubar.select_by_id('file-menu', 'menu_foobar') diff --git a/testing/firefox-ui/tests/puppeteer/test_notifications.py b/testing/firefox-ui/tests/puppeteer/test_notifications.py deleted file mode 100644 index de44c74349..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_notifications.py +++ /dev/null @@ -1,82 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.ui.browser.notifications import ( - AddOnInstallFailedNotification, - AddOnInstallConfirmationNotification, -) -from marionette_driver import By -from marionette_driver.errors import TimeoutException -from marionette_harness import MarionetteTestCase - - -class TestNotifications(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestNotifications, self).setUp() - - self.marionette.set_pref('extensions.install.requireSecureOrigin', False) - - self.addons_url = self.marionette.absolute_url('addons/extensions/') - self.puppeteer.utils.permissions.add(self.marionette.baseurl, 'install') - - def tearDown(self): - try: - self.marionette.clear_pref('extensions.install.requireSecureOrigin') - self.marionette.clear_pref('xpinstall.signatures.required') - - self.puppeteer.utils.permissions.remove(self.addons_url, 'install') - - if self.browser.notification: - self.browser.notification.close(force=True) - finally: - super(TestNotifications, self).tearDown() - - def test_open_close_notification(self): - """Trigger and dismiss a notification""" - self.assertIsNone(self.browser.notification) - self.trigger_addon_notification('restartless_addon_signed.xpi') - self.browser.notification.close() - self.assertIsNone(self.browser.notification) - - def test_wait_for_notification_timeout(self): - """Wait for a notification when one is not shown""" - message = 'No notification was shown' - with self.assertRaisesRegexp(TimeoutException, message): - self.browser.wait_for_notification() - - def test_wait_for_specific_notification_timeout(self): - """Wait for a notification when one is not shown""" - message = 'AddOnInstallFailedNotification was not shown' - with self.assertRaisesRegexp(TimeoutException, message): - self.browser.wait_for_notification(AddOnInstallFailedNotification) - - def test_wait_for_no_notification_timeout(self): - """Wait for no notification when one is shown""" - message = 'Unexpected notification shown' - self.trigger_addon_notification('restartless_addon_signed.xpi') - with self.assertRaisesRegexp(TimeoutException, message): - self.browser.wait_for_notification(None) - - def test_notification_with_origin(self): - """Trigger a notification with an origin""" - self.trigger_addon_notification('restartless_addon_signed.xpi') - self.assertIn(self.browser.notification.origin, self.marionette.baseurl) - self.assertIsNotNone(self.browser.notification.label) - - def test_addon_install_failed_notification(self): - """Trigger add-on blocked notification using an unsigned add-on""" - # Ensure that installing unsigned extensions will fail - self.marionette.set_pref('xpinstall.signatures.required', True) - - self.trigger_addon_notification( - 'restartless_addon_unsigned.xpi', - notification=AddOnInstallFailedNotification) - - def trigger_addon_notification(self, addon, notification=AddOnInstallConfirmationNotification): - with self.marionette.using_context('content'): - self.marionette.navigate(self.addons_url) - self.marionette.find_element(By.LINK_TEXT, addon).click() - self.browser.wait_for_notification(notification) diff --git a/testing/firefox-ui/tests/puppeteer/test_page_info_window.py b/testing/firefox-ui/tests/puppeteer/test_page_info_window.py deleted file mode 100644 index d86cbee3cb..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_page_info_window.py +++ /dev/null @@ -1,100 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_harness import MarionetteTestCase - - -class TestPageInfoWindow(PuppeteerMixin, MarionetteTestCase): - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestPageInfoWindow, self).tearDown() - - def test_elements(self): - """Test correct retrieval of elements.""" - page_info = self.browser.open_page_info_window() - - self.assertNotEqual(page_info.dtds, []) - self.assertNotEqual(page_info.properties, []) - - self.assertEqual(page_info.deck.element.get_property('localName'), 'deck') - - # feed panel - self.assertEqual(page_info.deck.feed.element.get_property('localName'), 'vbox') - - # general panel - self.assertEqual(page_info.deck.general.element.get_property('localName'), 'vbox') - - # media panel - self.assertEqual(page_info.deck.media.element.get_property('localName'), 'vbox') - - # permissions panel - self.assertEqual(page_info.deck.permissions.element.get_property('localName'), 'vbox') - - # security panel - panel = page_info.deck.select(page_info.deck.security) - - self.assertEqual(panel.element.get_property('localName'), 'vbox') - - self.assertEqual(panel.domain.get_property('localName'), 'textbox') - self.assertEqual(panel.owner.get_property('localName'), 'textbox') - self.assertEqual(panel.verifier.get_property('localName'), 'textbox') - - self.assertEqual(panel.view_certificate.get_property('localName'), 'button') - self.assertEqual(panel.view_cookies.get_property('localName'), 'button') - self.assertEqual(panel.view_passwords.get_property('localName'), 'button') - - def test_select(self): - """Test properties and methods for switching between panels.""" - page_info = self.browser.open_page_info_window() - deck = page_info.deck - - self.assertEqual(deck.selected_panel, deck.general) - - self.assertEqual(deck.select(deck.security), deck.security) - self.assertEqual(deck.selected_panel, deck.security) - - def test_open_window(self): - """Test various opening strategies.""" - def opener(win): - self.browser.menubar.select_by_id('tools-menu', 'menu_pageInfo') - - open_strategies = ('menu', - 'shortcut', - opener, - ) - - for trigger in open_strategies: - if trigger == 'shortcut' and self.puppeteer.platform == 'windows_nt': - # The shortcut for page info window does not exist on windows. - self.assertRaises(ValueError, self.browser.open_page_info_window, - trigger=trigger) - continue - - page_info = self.browser.open_page_info_window(trigger=trigger) - self.assertEquals(page_info, self.puppeteer.windows.current) - page_info.close() - - def test_close_window(self): - """Test various closing strategies.""" - def closer(win): - win.send_shortcut(win.localize_entity('closeWindow.key'), - accel=True) - - # Close a tab by each trigger method - close_strategies = ('menu', - 'shortcut', - closer, - ) - for trigger in close_strategies: - # menu only works on OS X - if trigger == 'menu' and self.puppeteer.platform != 'darwin': - continue - - page_info = self.browser.open_page_info_window() - page_info.close(trigger=trigger) - self.assertTrue(page_info.closed) diff --git a/testing/firefox-ui/tests/puppeteer/test_places.py b/testing/firefox-ui/tests/puppeteer/test_places.py deleted file mode 100644 index 95d0f23a45..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_places.py +++ /dev/null @@ -1,85 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import By, Wait -from marionette_harness import MarionetteTestCase - - -class TestPlaces(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestPlaces, self).setUp() - - self.urls = [self.marionette.absolute_url('layout/mozilla_governance.html'), - self.marionette.absolute_url('layout/mozilla_grants.html'), - ] - - def tearDown(self): - try: - self.puppeteer.places.restore_default_bookmarks() - self.puppeteer.places.remove_all_history() - finally: - super(TestPlaces, self).tearDown() - - def get_all_urls_in_history(self): - return self.marionette.execute_script(""" - let hs = Components.classes["@mozilla.org/browser/nav-history-service;1"] - .getService(Components.interfaces.nsINavHistoryService); - let urls = []; - - let options = hs.getNewQueryOptions(); - options.resultType = options.RESULTS_AS_URI; - - let root = hs.executeQuery(hs.getNewQuery(), options).root - root.containerOpen = true; - for (let i = 0; i < root.childCount; i++) { - urls.push(root.getChild(i).uri) - } - root.containerOpen = false; - - return urls; - """) - - def test_plugins(self): - # TODO: Once we use a plugin, add a test case to verify that the data will be removed - self.puppeteer.places.clear_plugin_data() - - def test_bookmarks(self): - star_button = self.marionette.find_element(By.ID, 'bookmarks-menu-button') - - # Visit URLs and bookmark them all - for url in self.urls: - with self.marionette.using_context('content'): - self.marionette.navigate(url) - - Wait(self.marionette).until( - lambda _: self.puppeteer.places.is_bookmark_star_button_ready()) - star_button.click() - Wait(self.marionette).until(lambda _: self.puppeteer.places.is_bookmarked(url)) - - ids = self.puppeteer.places.get_folder_ids_for_url(url) - self.assertEqual(len(ids), 1) - self.assertEqual(ids[0], self.puppeteer.places.bookmark_folders.unfiled) - - # Restore default bookmarks, so the added URLs are gone - self.puppeteer.places.restore_default_bookmarks() - for url in self.urls: - self.assertFalse(self.puppeteer.places.is_bookmarked(url)) - - def test_history(self): - self.assertEqual(len(self.get_all_urls_in_history()), 0) - - # Visit pages and check that they are all present - def load_urls(): - with self.marionette.using_context('content'): - for url in self.urls: - self.marionette.navigate(url) - self.puppeteer.places.wait_for_visited(self.urls, load_urls) - - self.assertEqual(self.get_all_urls_in_history(), self.urls) - - # Check that both pages are no longer in the remove_all_history - self.puppeteer.places.remove_all_history() - self.assertEqual(len(self.get_all_urls_in_history()), 0) diff --git a/testing/firefox-ui/tests/puppeteer/test_security.py b/testing/firefox-ui/tests/puppeteer/test_security.py deleted file mode 100644 index 879053e5a8..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_security.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.errors import NoCertificateError -from marionette_harness import MarionetteTestCase - - -class TestSecurity(PuppeteerMixin, MarionetteTestCase): - - def test_get_address_from_certificate(self): - url = 'https://ssl-ev.mozqa.com' - - with self.marionette.using_context(self.marionette.CONTEXT_CONTENT): - self.marionette.navigate(url) - - cert = self.browser.tabbar.tabs[0].certificate - self.assertIn(cert['commonName'], url) - self.assertEqual(cert['organization'], 'Mozilla Corporation') - self.assertEqual(cert['issuerOrganization'], 'DigiCert Inc') - - address = self.puppeteer.security.get_address_from_certificate(cert) - self.assertIsNotNone(address) - self.assertIsNotNone(address['city']) - self.assertIsNotNone(address['country']) - self.assertIsNotNone(address['postal_code']) - self.assertIsNotNone(address['state']) - self.assertIsNotNone(address['street']) - - def test_get_certificate(self): - url_http = self.marionette.absolute_url('layout/mozilla.html') - url_https = 'https://ssl-ev.mozqa.com' - - # Test EV certificate - with self.marionette.using_context(self.marionette.CONTEXT_CONTENT): - self.marionette.navigate(url_https) - cert = self.browser.tabbar.tabs[0].certificate - self.assertIn(cert['commonName'], url_https) - - # HTTP connections do not have a SSL certificate - with self.marionette.using_context(self.marionette.CONTEXT_CONTENT): - self.marionette.navigate(url_http) - with self.assertRaises(NoCertificateError): - self.browser.tabbar.tabs[0].certificate diff --git a/testing/firefox-ui/tests/puppeteer/test_software_update.py b/testing/firefox-ui/tests/puppeteer/test_software_update.py deleted file mode 100644 index 4bad47d94a..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_software_update.py +++ /dev/null @@ -1,134 +0,0 @@ -# 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 - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.api.software_update import SoftwareUpdate -from marionette_harness import MarionetteTestCase - - -class TestSoftwareUpdate(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSoftwareUpdate, self).setUp() - - self.software_update = SoftwareUpdate(self.marionette) - - self.saved_mar_channels = self.software_update.mar_channels.channels - self.software_update.mar_channels.channels = set(['expected', 'channels']) - - def tearDown(self): - try: - self.software_update.mar_channels.channels = self.saved_mar_channels - finally: - super(TestSoftwareUpdate, self).tearDown() - - def test_abi(self): - self.assertTrue(self.software_update.ABI) - - def test_allowed(self): - self.assertTrue(self.software_update.allowed) - - def test_build_info(self): - build_info = self.software_update.build_info - self.assertEqual(build_info['disabled_addons'], None) - self.assertIn('Mozilla/', build_info['user_agent']) - self.assertEqual(build_info['mar_channels'], set(['expected', 'channels'])) - self.assertTrue(build_info['version']) - self.assertTrue(build_info['buildid'].isdigit()) - self.assertTrue(build_info['locale']) - self.assertIn('force=1', build_info['update_url']) - self.assertIn('xml', build_info['update_snippet']) - self.assertEqual(build_info['channel'], self.software_update.update_channel) - - def test_force_fallback(self): - status_file = os.path.join(self.software_update.staging_directory, 'update.status') - - try: - self.software_update.force_fallback() - with open(status_file, 'r') as f: - content = f.read() - self.assertEqual(content, 'failed: 6\n') - finally: - os.remove(status_file) - - def test_get_update_url(self): - update_url = self.software_update.get_update_url() - self.assertIn('Firefox', update_url) - self.assertNotIn('force=1', update_url) - update_url = self.software_update.get_update_url(True) - self.assertIn('Firefox', update_url) - self.assertIn('force=1', update_url) - - def test_os_version(self): - self.assertTrue(self.software_update.os_version) - - def test_staging_directory(self): - self.assertTrue(self.software_update.staging_directory) - - -class TestUpdateChannel(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestUpdateChannel, self).setUp() - - self.software_update = SoftwareUpdate(self.marionette) - - self.saved_channel = self.software_update.update_channel - self.software_update.update_channel = 'expected_channel' - - def tearDown(self): - try: - self.software_update.update_channel = self.saved_channel - finally: - super(TestUpdateChannel, self).tearDown() - - def test_update_channel_default_channel(self): - # Without a restart the update channel will not change. - self.assertEqual(self.software_update.update_channel, self.saved_channel) - - def test_update_channel_set_channel(self): - try: - # Use the clean option to force a non in_app restart, which would allow - # Firefox to dump the logs to the console. - self.restart(clean=True) - self.assertEqual(self.software_update.update_channel, 'expected_channel') - finally: - self.software_update.update_channel = self.saved_channel - self.restart(clean=True) - - -class TestMARChannels(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestMARChannels, self).setUp() - - self.software_update = SoftwareUpdate(self.marionette) - - self.saved_mar_channels = self.software_update.mar_channels.channels - self.software_update.mar_channels.channels = set(['expected', 'channels']) - - def tearDown(self): - try: - self.software_update.mar_channels.channels = self.saved_mar_channels - finally: - super(TestMARChannels, self).tearDown() - - def test_mar_channels_channels(self): - self.assertEqual(self.software_update.mar_channels.channels, set(['expected', 'channels'])) - - def test_mar_channels_set_channels(self): - self.software_update.mar_channels.channels = set(['a', 'b', 'c']) - self.assertEqual(self.software_update.mar_channels.channels, set(['a', 'b', 'c'])) - - def test_mar_channels_add_channels(self): - self.software_update.mar_channels.add_channels(set(['some', 'new', 'channels'])) - self.assertEqual( - self.software_update.mar_channels.channels, - set(['expected', 'channels', 'some', 'new'])) - - def test_mar_channels_remove_channels(self): - self.software_update.mar_channels.remove_channels(set(['expected'])) - self.assertEqual(self.software_update.mar_channels.channels, set(['channels'])) diff --git a/testing/firefox-ui/tests/puppeteer/test_tabbar.py b/testing/firefox-ui/tests/puppeteer/test_tabbar.py deleted file mode 100644 index 7da3f7ee72..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_tabbar.py +++ /dev/null @@ -1,191 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.errors import NoCertificateError -from marionette_harness import MarionetteTestCase - - -class TestTabBar(PuppeteerMixin, MarionetteTestCase): - - def tearDown(self): - try: - self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]]) - finally: - super(TestTabBar, self).tearDown() - - def test_basics(self): - tabbar = self.browser.tabbar - - self.assertEqual(tabbar.window, self.browser) - - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - - self.assertEqual(tabbar.newtab_button.get_property('localName'), 'toolbarbutton') - self.assertEqual(tabbar.toolbar.get_property('localName'), 'tabs') - - def test_open_close(self): - tabbar = self.browser.tabbar - - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.selected_index, 0) - - # Open with default trigger, and force closing the tab - tabbar.open_tab() - tabbar.close_tab(force=True) - - # Open a new tab by each trigger method - open_strategies = ('button', - 'menu', - 'shortcut', - lambda tab: tabbar.newtab_button.click() - ) - for trigger in open_strategies: - new_tab = tabbar.open_tab(trigger=trigger) - self.assertEqual(len(tabbar.tabs), 2) - self.assertEqual(new_tab.handle, self.marionette.current_window_handle) - self.assertEqual(new_tab.handle, tabbar.tabs[1].handle) - - tabbar.close_tab() - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - self.assertNotEqual(new_tab.handle, tabbar.tabs[0].handle) - - # Close a tab by each trigger method - close_strategies = ('button', - 'menu', - 'shortcut', - lambda tab: tab.close_button.click()) - for trigger in close_strategies: - new_tab = tabbar.open_tab() - self.assertEqual(len(tabbar.tabs), 2) - self.assertEqual(new_tab.handle, self.marionette.current_window_handle) - self.assertEqual(new_tab.handle, tabbar.tabs[1].handle) - - tabbar.close_tab(trigger=trigger) - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - self.assertNotEqual(new_tab.handle, tabbar.tabs[0].handle) - - def test_close_not_selected_tab(self): - tabbar = self.browser.tabbar - - new_tab = tabbar.open_tab() - tabbar.close_tab(tabbar.tabs[0], trigger="button") - - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(new_tab, tabbar.tabs[0]) - - def test_close_all_tabs_except_first(self): - tabbar = self.browser.tabbar - - orig_tab = tabbar.tabs[0] - - for i in range(0, 3): - tabbar.open_tab() - - tabbar.close_all_tabs([orig_tab]) - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(orig_tab.handle, self.marionette.current_window_handle) - - def test_switch_to(self): - tabbar = self.browser.tabbar - - # Open a new tab in the foreground (will be auto-selected) - new_tab = tabbar.open_tab() - self.assertEqual(new_tab.handle, self.marionette.current_window_handle) - self.assertEqual(tabbar.selected_index, 1) - self.assertEqual(tabbar.selected_tab, new_tab) - - # Switch by index - tabbar.switch_to(0) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - - # Switch by tab - tabbar.switch_to(new_tab) - self.assertEqual(new_tab.handle, self.marionette.current_window_handle) - - # Switch by callback - tabbar.switch_to(lambda tab: tab.window.tabbar.selected_tab != tab) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - - tabbar.close_tab(tabbar.tabs[1]) - - -class TestTab(PuppeteerMixin, MarionetteTestCase): - - def tearDown(self): - try: - self.browser.tabbar.close_all_tabs([self.browser.tabbar.tabs[0]]) - finally: - super(TestTab, self).tearDown() - - def test_basic(self): - tab = self.browser.tabbar.tabs[0] - - self.assertEqual(tab.window, self.browser) - - self.assertEqual(tab.tab_element.get_property('localName'), 'tab') - self.assertEqual(tab.close_button.get_property('localName'), 'toolbarbutton') - - def test_certificate(self): - url = self.marionette.absolute_url('layout/mozilla.html') - - with self.marionette.using_context(self.marionette.CONTEXT_CONTENT): - self.marionette.navigate(url) - with self.assertRaises(NoCertificateError): - self.browser.tabbar.tabs[0].certificate - - def test_close(self): - tabbar = self.browser.tabbar - - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.selected_index, 0) - - # Force closing the tab - new_tab = tabbar.open_tab() - new_tab.close(force=True) - - # Close a tab by each trigger method - close_strategies = ('button', - 'menu', - 'shortcut', - lambda tab: tab.close_button.click()) - for trigger in close_strategies: - new_tab = tabbar.open_tab() - self.assertEqual(len(tabbar.tabs), 2) - self.assertEqual(new_tab.handle, self.marionette.current_window_handle) - self.assertEqual(new_tab.handle, tabbar.tabs[1].handle) - - new_tab.close(trigger=trigger) - self.assertEqual(len(tabbar.tabs), 1) - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - self.assertNotEqual(new_tab.handle, tabbar.tabs[0].handle) - - def test_location(self): - url = self.marionette.absolute_url('layout/mozilla.html') - with self.marionette.using_context(self.marionette.CONTEXT_CONTENT): - self.marionette.navigate(url) - self.assertEqual(self.browser.tabbar.tabs[0].location, url) - - def test_switch_to(self): - tabbar = self.browser.tabbar - - new_tab = tabbar.open_tab() - - # Switch to the first tab, which will not select it - tabbar.tabs[0].switch_to() - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - # Bug 1128656: We cannot test as long as switch_to_window() auto-selects the tab - # self.assertEqual(tabbar.selected_index, 1) - # self.assertEqual(tabbar.selected_tab, new_tab) - - # Now select the first tab - tabbar.tabs[0].select() - self.assertEqual(tabbar.tabs[0].handle, self.marionette.current_window_handle) - self.assertTrue(tabbar.tabs[0].selected) - self.assertFalse(tabbar.tabs[1].selected) - - new_tab.close() diff --git a/testing/firefox-ui/tests/puppeteer/test_toolbars.py b/testing/firefox-ui/tests/puppeteer/test_toolbars.py deleted file mode 100644 index 8150be7e15..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_toolbars.py +++ /dev/null @@ -1,283 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_driver import expected, By, Wait -from marionette_driver.errors import NoSuchElementException -from marionette_harness import MarionetteTestCase - - -class TestNavBar(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestNavBar, self).setUp() - - self.navbar = self.browser.navbar - self.url = self.marionette.absolute_url('layout/mozilla.html') - - with self.marionette.using_context('content'): - self.marionette.navigate('about:blank') - - # TODO: check why self.puppeteer.places.remove_all_history() does not work here - self.marionette.execute_script(""" - let count = gBrowser.sessionHistory.count; - gBrowser.sessionHistory.PurgeHistory(count); - """) - - def test_elements(self): - self.assertEqual(self.navbar.back_button.get_property('localName'), 'toolbarbutton') - self.assertEqual(self.navbar.forward_button.get_property('localName'), 'toolbarbutton') - self.assertEqual(self.navbar.home_button.get_property('localName'), 'toolbarbutton') - self.assertEqual(self.navbar.menu_button.get_property('localName'), 'toolbarbutton') - self.assertEqual(self.navbar.toolbar.get_property('localName'), 'toolbar') - - def test_buttons(self): - self.marionette.set_context('content') - - # Load initial web page - self.marionette.navigate(self.url) - Wait(self.marionette).until(expected.element_present(lambda m: - m.find_element(By.ID, 'mozilla_logo'))) - - with self.marionette.using_context('chrome'): - # Both buttons are disabled - self.assertFalse(self.navbar.back_button.is_enabled()) - self.assertFalse(self.navbar.forward_button.is_enabled()) - - # Go to the homepage - self.navbar.home_button.click() - - Wait(self.marionette).until(expected.element_not_present(lambda m: - m.find_element(By.ID, 'mozilla_logo'))) - self.assertEqual(self.marionette.get_url(), self.browser.default_homepage) - - with self.marionette.using_context('chrome'): - # Only back button is enabled - self.assertTrue(self.navbar.back_button.is_enabled()) - self.assertFalse(self.navbar.forward_button.is_enabled()) - - # Navigate back - self.navbar.back_button.click() - - Wait(self.marionette).until(expected.element_present(lambda m: - m.find_element(By.ID, 'mozilla_logo'))) - self.assertEqual(self.marionette.get_url(), self.url) - - with self.marionette.using_context('chrome'): - # Only forward button is enabled - self.assertFalse(self.navbar.back_button.is_enabled()) - self.assertTrue(self.navbar.forward_button.is_enabled()) - - # Navigate forward - self.navbar.forward_button.click() - - Wait(self.marionette).until(expected.element_not_present(lambda m: - m.find_element(By.ID, 'mozilla_logo'))) - self.assertEqual(self.marionette.get_url(), self.browser.default_homepage) - - -class TestLocationBar(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestLocationBar, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - - def test_elements(self): - self.assertEqual(self.locationbar.urlbar.get_property('localName'), 'textbox') - self.assertIn('urlbar-input', self.locationbar.urlbar_input.get_property('className')) - - self.assertEqual(self.locationbar.connection_icon.get_property('localName'), 'image') - self.assertEqual(self.locationbar.identity_box.get_property('localName'), 'box') - self.assertEqual(self.locationbar.identity_country_label.get_property('localName'), - 'label') - self.assertEqual(self.locationbar.identity_organization_label.get_property('localName'), - 'label') - self.assertEqual(self.locationbar.identity_icon.get_property('localName'), 'image') - self.assertEqual(self.locationbar.history_drop_marker.get_property('localName'), - 'dropmarker') - self.assertEqual(self.locationbar.reload_button.get_property('localName'), - 'toolbarbutton') - self.assertEqual(self.locationbar.stop_button.get_property('localName'), - 'toolbarbutton') - - self.assertEqual(self.locationbar.contextmenu.get_property('localName'), 'menupopup') - self.assertEqual(self.locationbar.get_contextmenu_entry('paste').get_attribute('cmd'), - 'cmd_paste') - - def test_reload(self): - event_types = ["shortcut", "shortcut2", "button"] - for event in event_types: - # TODO: Until we have waitForPageLoad, this only tests API - # compatibility. - self.locationbar.reload_url(event, force=True) - self.locationbar.reload_url(event, force=False) - - def test_focus_and_clear(self): - self.locationbar.urlbar.send_keys("zyx") - self.locationbar.clear() - self.assertEqual(self.locationbar.value, '') - - self.locationbar.urlbar.send_keys("zyx") - self.assertEqual(self.locationbar.value, 'zyx') - - self.locationbar.clear() - self.assertEqual(self.locationbar.value, '') - - def test_load_url(self): - data_uri = 'data:text/html,Title' - self.locationbar.load_url(data_uri) - - with self.marionette.using_context('content'): - Wait(self.marionette).until(lambda mn: mn.get_url() == data_uri) - - -class TestAutoCompleteResults(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestAutoCompleteResults, self).setUp() - - self.browser.navbar.locationbar.clear() - - self.autocomplete_results = self.browser.navbar.locationbar.autocomplete_results - - def tearDown(self): - try: - self.autocomplete_results.close(force=True) - except NoSuchElementException: - # TODO: A NoSuchElementException is thrown here when tests accessing the - # autocomplete_results element are skipped. - pass - finally: - super(TestAutoCompleteResults, self).tearDown() - - def test_popup_elements(self): - # TODO: This test is not very robust because it relies on the history - # in the default profile. - self.assertFalse(self.autocomplete_results.is_open) - self.browser.navbar.locationbar.urlbar.send_keys('a') - results = self.autocomplete_results.results - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_complete) - visible_result_count = len(self.autocomplete_results.visible_results) - self.assertTrue(visible_result_count > 0) - self.assertEqual(visible_result_count, - int(results.get_property('itemCount'))) - - def test_close(self): - self.browser.navbar.locationbar.urlbar.send_keys('a') - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open) - # The Wait in the library implementation will fail this if this doesn't - # end up closing. - self.autocomplete_results.close() - - def test_force_close(self): - self.browser.navbar.locationbar.urlbar.send_keys('a') - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open) - # The Wait in the library implementation will fail this if this doesn't - # end up closing. - self.autocomplete_results.close(force=True) - - def test_matching_text(self): - # The default profile always has existing bookmarks. So no sites have to - # be visited and bookmarked. - for input_text in ('about', 'zilla'): - self.browser.navbar.locationbar.urlbar.clear() - self.browser.navbar.locationbar.urlbar.send_keys(input_text) - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_open) - Wait(self.marionette).until(lambda _: self.autocomplete_results.is_complete) - visible_results = self.autocomplete_results.visible_results - self.assertTrue(len(visible_results) > 0) - - for result in visible_results: - # check matching text only for results of type bookmark - if result.get_attribute('type') != 'bookmark': - continue - title_matches = self.autocomplete_results.get_matching_text(result, "title") - url_matches = self.autocomplete_results.get_matching_text(result, "url") - all_matches = title_matches + url_matches - self.assertTrue(len(all_matches) > 0) - for match_fragment in all_matches: - self.assertIn(match_fragment.lower(), input_text) - - self.autocomplete_results.close() - - -class TestIdentityPopup(PuppeteerMixin, MarionetteTestCase): - def setUp(self): - super(TestIdentityPopup, self).setUp() - - self.locationbar = self.browser.navbar.locationbar - self.identity_popup = self.locationbar.identity_popup - - self.url = 'https://ssl-ev.mozqa.com' - - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - def tearDown(self): - try: - self.identity_popup.close(force=True) - finally: - super(TestIdentityPopup, self).tearDown() - - def test_elements(self): - self.locationbar.open_identity_popup() - - # Test main view elements - main = self.identity_popup.view.main - self.assertEqual(main.element.get_property('localName'), 'panelview') - - self.assertEqual(main.expander.get_property('localName'), 'button') - self.assertEqual(main.host.get_property('localName'), 'label') - self.assertEqual(main.insecure_connection_label.get_property('localName'), - 'description') - self.assertEqual(main.internal_connection_label.get_property('localName'), - 'description') - self.assertEqual(main.secure_connection_label.get_property('localName'), - 'description') - - self.assertEqual(main.permissions.get_property('localName'), 'vbox') - - # Test security view elements - security = self.identity_popup.view.security - self.assertEqual(security.element.get_property('localName'), 'panelview') - - self.assertEqual(security.host.get_property('localName'), 'label') - self.assertEqual(security.insecure_connection_label.get_property('localName'), - 'description') - self.assertEqual(security.secure_connection_label.get_property('localName'), - 'description') - - self.assertEqual(security.owner.get_property('localName'), 'description') - self.assertEqual(security.owner_location.get_property('localName'), 'description') - self.assertEqual(security.verifier.get_property('localName'), 'description') - - self.assertEqual(security.disable_mixed_content_blocking_button.get_property('localName'), - 'button') - self.assertEqual(security.enable_mixed_content_blocking_button.get_property('localName'), - 'button') - - self.assertEqual(security.more_info_button.get_property('localName'), 'button') - - def test_open_close(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.assertFalse(self.identity_popup.is_open) - - self.locationbar.open_identity_popup() - - self.identity_popup.close() - self.assertFalse(self.identity_popup.is_open) - - def test_force_close(self): - with self.marionette.using_context('content'): - self.marionette.navigate(self.url) - - self.assertFalse(self.identity_popup.is_open) - - self.locationbar.open_identity_popup() - - self.identity_popup.close(force=True) - self.assertFalse(self.identity_popup.is_open) diff --git a/testing/firefox-ui/tests/puppeteer/test_update_wizard.py b/testing/firefox-ui/tests/puppeteer/test_update_wizard.py deleted file mode 100644 index 7170ea8e25..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_update_wizard.py +++ /dev/null @@ -1,67 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.ui.deck import Panel -from firefox_puppeteer.ui.update_wizard import UpdateWizardDialog -from marionette_harness import MarionetteTestCase - - -class TestUpdateWizard(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestUpdateWizard, self).setUp() - - def opener(win): - self.marionette.execute_script(""" - let updatePrompt = Components.classes["@mozilla.org/updates/update-prompt;1"] - .createInstance(Components.interfaces.nsIUpdatePrompt); - updatePrompt.checkForUpdates(); - """) - - self.dialog = self.browser.open_window(callback=opener, - expected_window_class=UpdateWizardDialog) - self.wizard = self.dialog.wizard - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestUpdateWizard, self).tearDown() - - def test_basic(self): - self.assertEqual(self.dialog.window_type, 'Update:Wizard') - self.assertNotEqual(self.dialog.dtds, []) - self.assertNotEqual(self.dialog.properties, []) - - def test_elements(self): - """Test correct retrieval of elements.""" - self.assertEqual(self.wizard.element.get_property('localName'), 'wizard') - - buttons = ('cancel_button', 'extra1_button', 'extra2_button', - 'finish_button', 'next_button', 'previous_button', - ) - for button in buttons: - self.assertEqual(getattr(self.wizard, button).get_property('localName'), - 'button') - - panels = ('checking', 'downloading', 'dummy', 'error_patching', 'error', - 'error_extra', 'finished', 'finished_background', - 'manual_update', 'no_updates_found', 'updates_found_basic', - ) - for panel in panels: - self.assertEqual(getattr(self.wizard, panel).element.get_property('localName'), - 'wizardpage') - - # elements of the checking panel - self.assertEqual(self.wizard.checking.progress.get_property('localName'), - 'progressmeter') - - # elements of the downloading panel - self.assertEqual(self.wizard.downloading.progress.get_property('localName'), - 'progressmeter') - - # check wizard attributes - self.assertIsInstance(self.wizard.selected_index, int) - self.assertIsInstance(self.wizard.selected_panel, Panel) diff --git a/testing/firefox-ui/tests/puppeteer/test_utils.py b/testing/firefox-ui/tests/puppeteer/test_utils.py deleted file mode 100644 index 664722cce4..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_utils.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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/. - -from firefox_puppeteer import PuppeteerMixin -from marionette_harness import MarionetteTestCase - - -class TestSanitize(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - super(TestSanitize, self).setUp() - - # Clear all previous history and cookies. - self.puppeteer.places.remove_all_history() - with self.marionette.using_context('content'): - self.marionette.delete_all_cookies() - - self.urls = [ - 'layout/mozilla_projects.html', - 'layout/mozilla.html', - 'layout/mozilla_mission.html', - 'cookies/cookie_single.html' - ] - self.urls = [self.marionette.absolute_url(url) for url in self.urls] - - # Open the test urls, including the single cookie setting page. - def load_urls(): - with self.marionette.using_context('content'): - for url in self.urls: - self.marionette.navigate(url) - self.puppeteer.places.wait_for_visited(self.urls, load_urls) - - def test_sanitize_history(self): - """ Clears history. """ - self.assertEqual(self.puppeteer.places.get_all_urls_in_history(), self.urls) - self.puppeteer.utils.sanitize(data_type={"history": True}) - self.assertEqual(self.puppeteer.places.get_all_urls_in_history(), []) - - def test_sanitize_cookies(self): - """ Clears cookies. """ - with self.marionette.using_context('content'): - self.assertIsNotNone(self.marionette.get_cookie('litmus_1')) - - self.puppeteer.utils.sanitize(data_type={"cookies": True}) - - with self.marionette.using_context('content'): - self.assertIsNone(self.marionette.get_cookie('litmus_1')) diff --git a/testing/firefox-ui/tests/puppeteer/test_windows.py b/testing/firefox-ui/tests/puppeteer/test_windows.py deleted file mode 100644 index 1ba13fa375..0000000000 --- a/testing/firefox-ui/tests/puppeteer/test_windows.py +++ /dev/null @@ -1,259 +0,0 @@ -# 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 firefox_puppeteer.errors as errors - -from firefox_puppeteer import PuppeteerMixin -from firefox_puppeteer.ui.windows import BaseWindow -from marionette_driver import By, Wait -from marionette_driver.errors import NoSuchWindowException -from marionette_harness import MarionetteTestCase - - -class BaseWindowTestCase(PuppeteerMixin, MarionetteTestCase): - - def setUp(self): - """ - These tests open and close windows pretty rapidly, which - (since bug 1261842) can cause content processes to be - spawned and discarded in large numbers. By default, Firefox - has a 5 second timeout for shutting down content processes, - but we can get into cases where the content process just - doesn't have enough time to get itself all sorted before - the timeout gets hit, which results in the parent killing - the content process manually, which generates a crash report, - which causes these tests to orange. We side-step this by - setting dom.ipc.tabs.shutdownTimeoutSecs to 0, which disables - the shutdown timer. - """ - super(BaseWindowTestCase, self).setUp() - - self.marionette.set_pref('dom.ipc.tabs.shutdownTimeoutSecs', 0) - - def tearDown(self): - try: - self.marionette.clear_pref('dom.ipc.tabs.shutdownTimeoutSecs') - finally: - super(BaseWindowTestCase, self).tearDown() - - -class TestWindows(BaseWindowTestCase): - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - super(TestWindows, self).tearDown() - - def test_switch_to(self): - url = self.marionette.absolute_url('layout/mozilla.html') - - # Open two more windows - for index in range(0, 2): - self.marionette.execute_script(""" window.open(); """) - - windows = self.puppeteer.windows.all - self.assertEquals(len(windows), 3) - - # Switch to the 2nd window - self.puppeteer.windows.switch_to(windows[1].handle) - self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle) - - # TODO: Needs updated tabs module for improved navigation - with self.marionette.using_context('content'): - self.marionette.navigate(url) - - # Switch to the last window and find 2nd window by URL - self.puppeteer.windows.switch_to(windows[2].handle) - - # TODO: A window can have multiple tabs, so this may need an update - # when the tabs module gets implemented - def find_by_url(win): - with win.marionette.using_context('content'): - return win.marionette.get_url() == url - - self.puppeteer.windows.switch_to(find_by_url) - self.assertEquals(windows[1].handle, self.marionette.current_chrome_window_handle) - - self.puppeteer.windows.switch_to(find_by_url) - - # Switching to an unknown handles has to fail - self.assertRaises(NoSuchWindowException, - self.puppeteer.windows.switch_to, "humbug") - self.assertRaises(NoSuchWindowException, - self.puppeteer.windows.switch_to, lambda win: False) - - self.puppeteer.windows.close_all([self.browser]) - self.browser.switch_to() - - self.assertEqual(len(self.puppeteer.windows.all), 1) - - def test_switch_to_unknown_window_type(self): - def open_by_js(_): - with self.marionette.using_context('chrome'): - self.marionette.execute_script(""" - window.open('chrome://browser/content/safeMode.xul', '_blank', - 'chrome,centerscreen,resizable=no'); - """) - - win = self.browser.open_window(callback=open_by_js, expected_window_class=BaseWindow) - win.close() - self.browser.switch_to() - - -class TestBaseWindow(BaseWindowTestCase): - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - BaseWindowTestCase.tearDown(self) - - def test_basics(self): - # force BaseWindow instance - win1 = BaseWindow(self.marionette, self.browser.handle) - - self.assertEquals(win1.handle, self.marionette.current_chrome_window_handle) - self.assertEquals(win1.window_element, - self.marionette.find_element(By.CSS_SELECTOR, ':root')) - self.assertEquals(win1.window_element.get_attribute('windowtype'), - self.marionette.get_window_type()) - self.assertFalse(win1.closed) - - # Test invalid parameters for BaseWindow constructor - self.assertRaises(errors.UnknownWindowError, - BaseWindow, self.marionette, 10) - - # Test invalid shortcuts - self.assertRaises(KeyError, - win1.send_shortcut, 'l', acel=True) - - def test_open_close(self): - # force BaseWindow instance - win1 = BaseWindow(self.marionette, self.browser.handle) - - # Open a new window (will be focused), and check states - win2 = win1.open_window() - - # force BaseWindow instance - win2 = BaseWindow(self.marionette, win2.handle) - - self.assertEquals(len(self.marionette.chrome_window_handles), 2) - self.assertNotEquals(win1.handle, win2.handle) - self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle) - - win2.close() - - self.assertTrue(win2.closed) - self.assertEquals(len(self.marionette.chrome_window_handles), 1) - self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle) - Wait(self.marionette).until(lambda _: win1.focused) # catch the no focused window - - win1.focus() - - # Open and close a new window by a custom callback - def opener(window): - window.marionette.execute_script(""" window.open(); """) - - def closer(window): - window.marionette.execute_script(""" window.close(); """) - - win2 = win1.open_window(callback=opener) - - # force BaseWindow instance - win2 = BaseWindow(self.marionette, win2.handle) - - self.assertEquals(len(self.marionette.chrome_window_handles), 2) - win2.close(callback=closer) - - win1.focus() - - # Check for an unexpected window class - self.assertRaises(errors.UnexpectedWindowTypeError, - win1.open_window, expected_window_class=BaseWindow) - self.puppeteer.windows.close_all([win1]) - - def test_switch_to_and_focus(self): - # force BaseWindow instance - win1 = BaseWindow(self.marionette, self.browser.handle) - - # Open a new window (will be focused), and check states - win2 = win1.open_window() - - # force BaseWindow instance - win2 = BaseWindow(self.marionette, win2.handle) - - self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle) - self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle) - self.assertFalse(win1.focused) - self.assertTrue(win2.focused) - - # Switch back to win1 without moving the focus, but focus separately - win1.switch_to() - self.assertEquals(win1.handle, self.marionette.current_chrome_window_handle) - self.assertTrue(win2.focused) - - win1.focus() - self.assertTrue(win1.focused) - - # Switch back to win2 by focusing it directly - win2.focus() - self.assertEquals(win2.handle, self.marionette.current_chrome_window_handle) - self.assertEquals(win2.handle, self.puppeteer.windows.focused_chrome_window_handle) - self.assertTrue(win2.focused) - - # Close win2, and check that it keeps active but looses focus - win2.switch_to() - win2.close() - - win1.switch_to() - - -class TestBrowserWindow(BaseWindowTestCase): - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - BaseWindowTestCase.tearDown(self) - - def test_basic(self): - self.assertNotEqual(self.browser.dtds, []) - self.assertNotEqual(self.browser.properties, []) - - self.assertFalse(self.browser.is_private) - - self.assertIsNotNone(self.browser.menubar) - self.assertIsNotNone(self.browser.navbar) - self.assertIsNotNone(self.browser.tabbar) - - def test_open_close(self): - # open and close a new browser windows by menu - win2 = self.browser.open_browser(trigger='menu') - self.assertEquals(win2, self.puppeteer.windows.current) - self.assertFalse(self.browser.is_private) - win2.close(trigger='menu') - - # open and close a new browser window by shortcut - win2 = self.browser.open_browser(trigger='shortcut') - self.assertEquals(win2, self.puppeteer.windows.current) - self.assertFalse(self.browser.is_private) - win2.close(trigger='shortcut') - - # open and close a new private browsing window - win2 = self.browser.open_browser(is_private=True) - self.assertEquals(win2, self.puppeteer.windows.current) - self.assertTrue(win2.is_private) - win2.close() - - # open and close a new private browsing window - win2 = self.browser.open_browser(trigger='shortcut', is_private=True) - self.assertEquals(win2, self.puppeteer.windows.current) - self.assertTrue(win2.is_private) - win2.close() - - # force closing a window - win2 = self.browser.open_browser() - self.assertEquals(win2, self.puppeteer.windows.current) - win2.close(force=True) diff --git a/testing/firefox-ui/tests/update/direct/manifest.ini b/testing/firefox-ui/tests/update/direct/manifest.ini deleted file mode 100644 index f5edb3c109..0000000000 --- a/testing/firefox-ui/tests/update/direct/manifest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -tags = direct - -[test_direct_update.py] diff --git a/testing/firefox-ui/tests/update/direct/test_direct_update.py b/testing/firefox-ui/tests/update/direct/test_direct_update.py deleted file mode 100644 index 41842349e1..0000000000 --- a/testing/firefox-ui/tests/update/direct/test_direct_update.py +++ /dev/null @@ -1,21 +0,0 @@ -# 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/. - -from firefox_ui_harness.testcases import UpdateTestCase - - -class TestDirectUpdate(UpdateTestCase): - - def setUp(self): - UpdateTestCase.setUp(self, is_fallback=False) - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - UpdateTestCase.tearDown(self) - - def test_update(self): - self.download_and_apply_available_update(force_fallback=False) - self.check_update_applied() diff --git a/testing/firefox-ui/tests/update/fallback/manifest.ini b/testing/firefox-ui/tests/update/fallback/manifest.ini deleted file mode 100644 index 704686db7d..0000000000 --- a/testing/firefox-ui/tests/update/fallback/manifest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -tags = fallback - -[test_fallback_update.py] diff --git a/testing/firefox-ui/tests/update/fallback/test_fallback_update.py b/testing/firefox-ui/tests/update/fallback/test_fallback_update.py deleted file mode 100644 index 264142bd82..0000000000 --- a/testing/firefox-ui/tests/update/fallback/test_fallback_update.py +++ /dev/null @@ -1,22 +0,0 @@ -# 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/. - -from firefox_ui_harness.testcases import UpdateTestCase - - -class TestFallbackUpdate(UpdateTestCase): - - def setUp(self): - UpdateTestCase.setUp(self, is_fallback=True) - - def tearDown(self): - try: - self.puppeteer.windows.close_all([self.browser]) - finally: - UpdateTestCase.tearDown(self) - - def test_update(self): - self.download_and_apply_available_update(force_fallback=True) - self.download_and_apply_forced_update() - self.check_update_applied() diff --git a/testing/firefox-ui/tests/update/manifest.ini b/testing/firefox-ui/tests/update/manifest.ini deleted file mode 100644 index 2a126e3318..0000000000 --- a/testing/firefox-ui/tests/update/manifest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[include:direct/manifest.ini] -[include:fallback/manifest.ini] diff --git a/testing/mach_commands.py b/testing/mach_commands.py index 866bc530ca..a744b0c44f 100644 --- a/testing/mach_commands.py +++ b/testing/mach_commands.py @@ -56,16 +56,6 @@ TEST_SUITES = { 'mach_command': 'crashtest', 'kwargs': {'test_file': None}, }, - 'firefox-ui-functional': { - 'aliases': ('Fxfn',), - 'mach_command': 'firefox-ui-functional', - 'kwargs': {}, - }, - 'firefox-ui-update': { - 'aliases': ('Fxup',), - 'mach_command': 'firefox-ui-update', - 'kwargs': {}, - }, 'jetpack': { 'aliases': ('J',), 'mach_command': 'jetpack-test', @@ -139,18 +129,6 @@ TEST_FLAVORS = { 'mach_command': 'mochitest', 'kwargs': {'flavor': 'chrome', 'test_paths': []}, }, - 'firefox-ui-functional': { - 'mach_command': 'firefox-ui-functional', - 'kwargs': {'tests': []}, - }, - 'firefox-ui-update': { - 'mach_command': 'firefox-ui-update', - 'kwargs': {'tests': []}, - }, - 'marionette': { - 'mach_command': 'marionette-test', - 'kwargs': {'tests': []}, - }, 'mochitest': { 'mach_command': 'mochitest', 'kwargs': {'flavor': 'mochitest', 'test_paths': []}, diff --git a/testing/marionette/accessibility.js b/testing/marionette/accessibility.js deleted file mode 100644 index 4ada0b88d3..0000000000 --- a/testing/marionette/accessibility.js +++ /dev/null @@ -1,441 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Log.jsm"); - -const logger = Log.repository.getLogger("Marionette"); - -Cu.import("chrome://marionette/content/error.js"); - -XPCOMUtils.defineLazyModuleGetter( - this, "setInterval", "resource://gre/modules/Timer.jsm"); -XPCOMUtils.defineLazyModuleGetter( - this, "clearInterval", "resource://gre/modules/Timer.jsm"); - -XPCOMUtils.defineLazyGetter(this, "service", () => { - let service; - try { - service = Cc["@mozilla.org/accessibilityService;1"].getService( - Ci.nsIAccessibilityService); - } catch (e) { - logger.warn("Accessibility module is not present"); - } finally { - return service; - } -}); - -this.EXPORTED_SYMBOLS = ["accessibility"]; - -/** - * Number of attempts to get an accessible object for an element. - * We attempt more than once because accessible tree can be out of sync - * with the DOM tree for a short period of time. - */ -const GET_ACCESSIBLE_ATTEMPTS = 100; - -/** - * An interval between attempts to retrieve an accessible object for an - * element. - */ -const GET_ACCESSIBLE_ATTEMPT_INTERVAL = 10; - -this.accessibility = { - get service() { - return service; - } -}; - -/** - * Accessible states used to check element"s state from the accessiblity API - * perspective. - * Note: if gecko is built with --disable-accessibility, the interfaces are not - * defined. This is why we use getters instead to be able to use these - * statically. - */ -accessibility.State = { - get Unavailable() { - return Ci.nsIAccessibleStates.STATE_UNAVAILABLE; - }, - get Focusable() { - return Ci.nsIAccessibleStates.STATE_FOCUSABLE; - }, - get Selectable() { - return Ci.nsIAccessibleStates.STATE_SELECTABLE; - }, - get Selected() { - return Ci.nsIAccessibleStates.STATE_SELECTED; - } -}; - -/** - * Accessible object roles that support some action. - */ -accessibility.ActionableRoles = new Set([ - "checkbutton", - "check menu item", - "check rich option", - "combobox", - "combobox option", - "entry", - "key", - "link", - "listbox option", - "listbox rich option", - "menuitem", - "option", - "outlineitem", - "pagetab", - "pushbutton", - "radiobutton", - "radio menu item", - "rowheader", - "slider", - "spinbutton", - "switch", -]); - - -/** - * Factory function that constructs a new {@code accessibility.Checks} - * object with enforced strictness or not. - */ -accessibility.get = function (strict = false) { - return new accessibility.Checks(!!strict); -}; - -/** - * Component responsible for interacting with platform accessibility - * API. - * - * Its methods serve as wrappers for testing content and chrome - * accessibility as well as accessibility of user interactions. - */ -accessibility.Checks = class { - - /** - * @param {boolean} strict - * Flag indicating whether the accessibility issue should be logged - * or cause an error to be thrown. Default is to log to stdout. - */ - constructor(strict) { - this.strict = strict; - } - - /** - * Get an accessible object for an element. - * - * @param {DOMElement|XULElement} element - * Element to get the accessible object for. - * @param {boolean=} mustHaveAccessible - * Flag indicating that the element must have an accessible object. - * Defaults to not require this. - * - * @return {Promise: nsIAccessible} - * Promise with an accessibility object for the given element. - */ - getAccessible(element, mustHaveAccessible = false) { - if (!this.strict) { - return Promise.resolve(); - } - - return new Promise((resolve, reject) => { - if (!accessibility.service) { - reject(); - return; - } - - let acc = accessibility.service.getAccessibleFor(element); - if (acc || !mustHaveAccessible) { - // if accessible object is found, return it; - // if it is not required, also resolve - resolve(acc); - } else { - // if we require an accessible object, we need to poll for it - // because accessible tree might be - // out of sync with DOM tree for a short time - let attempts = GET_ACCESSIBLE_ATTEMPTS; - let intervalId = setInterval(() => { - let acc = accessibility.service.getAccessibleFor(element); - if (acc || --attempts <= 0) { - clearInterval(intervalId); - if (acc) { - resolve(acc); - } else { - reject(); - } - } - }, GET_ACCESSIBLE_ATTEMPT_INTERVAL); - } - }).catch(() => this.error( - "Element does not have an accessible object", element)); - }; - - /** - * Test if the accessible has a role that supports some arbitrary - * action. - * - * @param {nsIAccessible} accessible - * Accessible object. - * - * @return {boolean} - * True if an actionable role is found on the accessible, false - * otherwise. - */ - isActionableRole(accessible) { - return accessibility.ActionableRoles.has( - accessibility.service.getStringRole(accessible.role)); - } - - /** - * Test if an accessible has at least one action that it supports. - * - * @param {nsIAccessible} accessible - * Accessible object. - * - * @return {boolean} - * True if the accessible has at least one supported action, - * false otherwise. - */ - hasActionCount(accessible) { - return accessible.actionCount > 0; - } - - /** - * Test if an accessible has a valid name. - * - * @param {nsIAccessible} accessible - * Accessible object. - * - * @return {boolean} - * True if the accessible has a non-empty valid name, or false if - * this is not the case. - */ - hasValidName(accessible) { - return accessible.name && accessible.name.trim(); - } - - /** - * Test if an accessible has a {@code hidden} attribute. - * - * @param {nsIAccessible} accessible - * Accessible object. - * - * @return {boolean} - * True if the accesible object has a {@code hidden} attribute, - * false otherwise. - */ - hasHiddenAttribute(accessible) { - let hidden = false; - try { - hidden = accessible.attributes.getStringProperty("hidden"); - } finally { - // if the property is missing, error will be thrown - return hidden && hidden === "true"; - } - } - - /** - * Verify if an accessible has a given state. - * Test if an accessible has a given state. - * - * @param {nsIAccessible} accessible - * Accessible object to test. - * @param {number} stateToMatch - * State to match. - * - * @return {boolean} - * True if |accessible| has |stateToMatch|, false otherwise. - */ - matchState(accessible, stateToMatch) { - let state = {}; - accessible.getState(state, {}); - return !!(state.value & stateToMatch); - } - - /** - * Test if an accessible is hidden from the user. - * - * @param {nsIAccessible} accessible - * Accessible object. - * - * @return {boolean} - * True if element is hidden from user, false otherwise. - */ - isHidden(accessible) { - while (accessible) { - if (this.hasHiddenAttribute(accessible)) { - return true; - } - accessible = accessible.parent; - } - return false; - } - - /** - * Test if the element's visible state corresponds to its accessibility - * API visibility. - * - * @param {nsIAccessible} accessible - * Accessible object. - * @param {DOMElement|XULElement} element - * Element associated with |accessible|. - * @param {boolean} visible - * Visibility state of |element|. - * - * @throws ElementNotAccessibleError - * If |element|'s visibility state does not correspond to - * |accessible|'s. - */ - assertVisible(accessible, element, visible) { - if (!accessible) { - return; - } - - let hiddenAccessibility = this.isHidden(accessible); - - let message; - if (visible && hiddenAccessibility) { - message = "Element is not currently visible via the accessibility API " + - "and may not be manipulated by it"; - } else if (!visible && !hiddenAccessibility) { - message = "Element is currently only visible via the accessibility API " + - "and can be manipulated by it"; - } - this.error(message, element); - } - - /** - * Test if the element's unavailable accessibility state matches the - * enabled state. - * - * @param {nsIAccessible} accessible - * Accessible object. - * @param {DOMElement|XULElement} element - * Element associated with |accessible|. - * @param {boolean} enabled - * Enabled state of |element|. - * - * @throws ElementNotAccessibleError - * If |element|'s enabled state does not match |accessible|'s. - */ - assertEnabled(accessible, element, enabled) { - if (!accessible) { - return; - } - - let win = element.ownerDocument.defaultView; - let disabledAccessibility = this.matchState( - accessible, accessibility.State.Unavailable); - let explorable = win.getComputedStyle(element) - .getPropertyValue("pointer-events") !== "none"; - - let message; - if (!explorable && !disabledAccessibility) { - message = "Element is enabled but is not explorable via the " + - "accessibility API"; - } else if (enabled && disabledAccessibility) { - message = "Element is enabled but disabled via the accessibility API"; - } else if (!enabled && !disabledAccessibility) { - message = "Element is disabled but enabled via the accessibility API"; - } - this.error(message, element); - } - - /** - * Test if it is possible to activate an element with the accessibility - * API. - * - * @param {nsIAccessible} accessible - * Accessible object. - * @param {DOMElement|XULElement} element - * Element associated with |accessible|. - * - * @throws ElementNotAccessibleError - * If it is impossible to activate |element| with |accessible|. - */ - assertActionable(accessible, element) { - if (!accessible) { - return; - } - - let message; - if (!this.hasActionCount(accessible)) { - message = "Element does not support any accessible actions"; - } else if (!this.isActionableRole(accessible)) { - message = "Element does not have a correct accessibility role " + - "and may not be manipulated via the accessibility API"; - } else if (!this.hasValidName(accessible)) { - message = "Element is missing an accessible name"; - } else if (!this.matchState(accessible, accessibility.State.Focusable)) { - message = "Element is not focusable via the accessibility API"; - } - - this.error(message, element); - } - - /** - * Test that an element's selected state corresponds to its - * accessibility API selected state. - * - * @param {nsIAccessible} accessible - * Accessible object. - * @param {DOMElement|XULElement} - * Element associated with |accessible|. - * @param {boolean} selected - * The |element|s selected state. - * - * @throws ElementNotAccessibleError - * If |element|'s selected state does not correspond to - * |accessible|'s. - */ - assertSelected(accessible, element, selected) { - if (!accessible) { - return; - } - - // element is not selectable via the accessibility API - if (!this.matchState(accessible, accessibility.State.Selectable)) { - return; - } - - let selectedAccessibility = this.matchState(accessible, accessibility.State.Selected); - - let message; - if (selected && !selectedAccessibility) { - message = "Element is selected but not selected via the accessibility API"; - } else if (!selected && selectedAccessibility) { - message = "Element is not selected but selected via the accessibility API"; - } - this.error(message, element); - } - - /** - * Throw an error if strict accessibility checks are enforced and log - * the error to the log. - * - * @param {string} message - * @param {DOMElement|XULElement} element - * Element that caused an error. - * - * @throws ElementNotAccessibleError - * If |strict| is true. - */ - error(message, element) { - if (!message || !this.strict) { - return; - } - if (element) { - let {id, tagName, className} = element; - message += `: id: ${id}, tagName: ${tagName}, className: ${className}`; - } - - throw new ElementNotAccessibleError(message); - } - -}; diff --git a/testing/marionette/action.js b/testing/marionette/action.js deleted file mode 100644 index 2eb39810be..0000000000 --- a/testing/marionette/action.js +++ /dev/null @@ -1,1348 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Task.jsm"); - -Cu.import("chrome://marionette/content/assert.js"); -Cu.import("chrome://marionette/content/element.js"); -Cu.import("chrome://marionette/content/error.js"); -Cu.import("chrome://marionette/content/event.js"); - -this.EXPORTED_SYMBOLS = ["action"]; - -// TODO? With ES 2016 and Symbol you can make a safer approximation -// to an enum e.g. https://gist.github.com/xmlking/e86e4f15ec32b12c4689 -/** - * Implements WebDriver Actions API: a low-level interface for providing - * virtualised device input to the web browser. - */ -this.action = { - Pause: "pause", - KeyDown: "keyDown", - KeyUp: "keyUp", - PointerDown: "pointerDown", - PointerUp: "pointerUp", - PointerMove: "pointerMove", - PointerCancel: "pointerCancel", -}; - -const ACTIONS = { - none: new Set([action.Pause]), - key: new Set([action.Pause, action.KeyDown, action.KeyUp]), - pointer: new Set([ - action.Pause, - action.PointerDown, - action.PointerUp, - action.PointerMove, - action.PointerCancel, - ]), -}; - -/** Map from normalized key value to UI Events modifier key name */ -const MODIFIER_NAME_LOOKUP = { - "Alt": "alt", - "Shift": "shift", - "Control": "ctrl", - "Meta": "meta", -}; - -/** Map from raw key (codepoint) to normalized key value */ -const NORMALIZED_KEY_LOOKUP = { - "\uE000": "Unidentified", - "\uE001": "Cancel", - "\uE002": "Help", - "\uE003": "Backspace", - "\uE004": "Tab", - "\uE005": "Clear", - "\uE006": "Return", - "\uE007": "Enter", - "\uE008": "Shift", - "\uE009": "Control", - "\uE00A": "Alt", - "\uE00B": "Pause", - "\uE00C": "Escape", - "\uE00D": " ", - "\uE00E": "PageUp", - "\uE00F": "PageDown", - "\uE010": "End", - "\uE011": "Home", - "\uE012": "ArrowLeft", - "\uE013": "ArrowUp", - "\uE014": "ArrowRight", - "\uE015": "ArrowDown", - "\uE016": "Insert", - "\uE017": "Delete", - "\uE018": ";", - "\uE019": "=", - "\uE01A": "0", - "\uE01B": "1", - "\uE01C": "2", - "\uE01D": "3", - "\uE01E": "4", - "\uE01F": "5", - "\uE020": "6", - "\uE021": "7", - "\uE022": "8", - "\uE023": "9", - "\uE024": "*", - "\uE025": "+", - "\uE026": ",", - "\uE027": "-", - "\uE028": ".", - "\uE029": "/", - "\uE031": "F1", - "\uE032": "F2", - "\uE033": "F3", - "\uE034": "F4", - "\uE035": "F5", - "\uE036": "F6", - "\uE037": "F7", - "\uE038": "F8", - "\uE039": "F9", - "\uE03A": "F10", - "\uE03B": "F11", - "\uE03C": "F12", - "\uE03D": "Meta", - "\uE040": "ZenkakuHankaku", - "\uE050": "Shift", - "\uE051": "Control", - "\uE052": "Alt", - "\uE053": "Meta", - "\uE054": "PageUp", - "\uE055": "PageDown", - "\uE056": "End", - "\uE057": "Home", - "\uE058": "ArrowLeft", - "\uE059": "ArrowUp", - "\uE05A": "ArrowRight", - "\uE05B": "ArrowDown", - "\uE05C": "Insert", - "\uE05D": "Delete", -}; - -/** Map from raw key (codepoint) to key location */ -const KEY_LOCATION_LOOKUP = { - "\uE007": 1, - "\uE008": 1, - "\uE009": 1, - "\uE00A": 1, - "\uE01A": 3, - "\uE01B": 3, - "\uE01C": 3, - "\uE01D": 3, - "\uE01E": 3, - "\uE01F": 3, - "\uE020": 3, - "\uE021": 3, - "\uE022": 3, - "\uE023": 3, - "\uE024": 3, - "\uE025": 3, - "\uE026": 3, - "\uE027": 3, - "\uE028": 3, - "\uE029": 3, - "\uE03D": 1, - "\uE050": 2, - "\uE051": 2, - "\uE052": 2, - "\uE053": 2, - "\uE054": 3, - "\uE055": 3, - "\uE056": 3, - "\uE057": 3, - "\uE058": 3, - "\uE059": 3, - "\uE05A": 3, - "\uE05B": 3, - "\uE05C": 3, - "\uE05D": 3, -}; - -const KEY_CODE_LOOKUP = { - "\uE00A": "AltLeft", - "\uE052": "AltRight", - "\uE015": "ArrowDown", - "\uE012": "ArrowLeft", - "\uE014": "ArrowRight", - "\uE013": "ArrowUp", - "`": "Backquote", - "~": "Backquote", - "\\": "Backslash", - "|": "Backslash", - "\uE003": "Backspace", - "[": "BracketLeft", - "{": "BracketLeft", - "]": "BracketRight", - "}": "BracketRight", - ",": "Comma", - "<": "Comma", - "\uE009": "ControlLeft", - "\uE051": "ControlRight", - "\uE017": "Delete", - ")": "Digit0", - "0": "Digit0", - "!": "Digit1", - "1": "Digit1", - "2": "Digit2", - "@": "Digit2", - "#": "Digit3", - "3": "Digit3", - "$": "Digit4", - "4": "Digit4", - "%": "Digit5", - "5": "Digit5", - "6": "Digit6", - "^": "Digit6", - "&": "Digit7", - "7": "Digit7", - "*": "Digit8", - "8": "Digit8", - "(": "Digit9", - "9": "Digit9", - "\uE010": "End", - "\uE006": "Enter", - "+": "Equal", - "=": "Equal", - "\uE00C": "Escape", - "\uE031": "F1", - "\uE03A": "F10", - "\uE03B": "F11", - "\uE03C": "F12", - "\uE032": "F2", - "\uE033": "F3", - "\uE034": "F4", - "\uE035": "F5", - "\uE036": "F6", - "\uE037": "F7", - "\uE038": "F8", - "\uE039": "F9", - "\uE002": "Help", - "\uE011": "Home", - "\uE016": "Insert", - "<": "IntlBackslash", - ">": "IntlBackslash", - "A": "KeyA", - "a": "KeyA", - "B": "KeyB", - "b": "KeyB", - "C": "KeyC", - "c": "KeyC", - "D": "KeyD", - "d": "KeyD", - "E": "KeyE", - "e": "KeyE", - "F": "KeyF", - "f": "KeyF", - "G": "KeyG", - "g": "KeyG", - "H": "KeyH", - "h": "KeyH", - "I": "KeyI", - "i": "KeyI", - "J": "KeyJ", - "j": "KeyJ", - "K": "KeyK", - "k": "KeyK", - "L": "KeyL", - "l": "KeyL", - "M": "KeyM", - "m": "KeyM", - "N": "KeyN", - "n": "KeyN", - "O": "KeyO", - "o": "KeyO", - "P": "KeyP", - "p": "KeyP", - "Q": "KeyQ", - "q": "KeyQ", - "R": "KeyR", - "r": "KeyR", - "S": "KeyS", - "s": "KeyS", - "T": "KeyT", - "t": "KeyT", - "U": "KeyU", - "u": "KeyU", - "V": "KeyV", - "v": "KeyV", - "W": "KeyW", - "w": "KeyW", - "X": "KeyX", - "x": "KeyX", - "Y": "KeyY", - "y": "KeyY", - "Z": "KeyZ", - "z": "KeyZ", - "-": "Minus", - "_": "Minus", - "\uE01A": "Numpad0", - "\uE05C": "Numpad0", - "\uE01B": "Numpad1", - "\uE056": "Numpad1", - "\uE01C": "Numpad2", - "\uE05B": "Numpad2", - "\uE01D": "Numpad3", - "\uE055": "Numpad3", - "\uE01E": "Numpad4", - "\uE058": "Numpad4", - "\uE01F": "Numpad5", - "\uE020": "Numpad6", - "\uE05A": "Numpad6", - "\uE021": "Numpad7", - "\uE057": "Numpad7", - "\uE022": "Numpad8", - "\uE059": "Numpad8", - "\uE023": "Numpad9", - "\uE054": "Numpad9", - "\uE024": "NumpadAdd", - "\uE026": "NumpadComma", - "\uE028": "NumpadDecimal", - "\uE05D": "NumpadDecimal", - "\uE029": "NumpadDivide", - "\uE007": "NumpadEnter", - "\uE024": "NumpadMultiply", - "\uE026": "NumpadSubtract", - "\uE03D": "OSLeft", - "\uE053": "OSRight", - "\uE01E": "PageDown", - "\uE01F": "PageUp", - ".": "Period", - ">": "Period", - "\"": "Quote", - "'": "Quote", - ":": "Semicolon", - ";": "Semicolon", - "\uE008": "ShiftLeft", - "\uE050": "ShiftRight", - "/": "Slash", - "?": "Slash", - "\uE00D": "Space", - " ": "Space", - "\uE004": "Tab", -}; - -/** Represents possible values for a pointer-move origin. */ -action.PointerOrigin = { - Viewport: "viewport", - Pointer: "pointer", -}; - -/** - * Look up a PointerOrigin. - * - * @param {?} obj - * Origin for a pointerMove action. - * - * @return {?} - * A pointer origin that is either "viewport" (default), "pointer", or a - * web-element reference. - * - * @throws {InvalidArgumentError} - * If |obj| is not a valid origin. - */ -action.PointerOrigin.get = function(obj) { - let origin = obj; - if (typeof obj == "undefined") { - origin = this.Viewport; - } else if (typeof obj == "string") { - let name = capitalize(obj); - assert.in(name, this, error.pprint`Unknown pointer-move origin: ${obj}`); - origin = this[name]; - } else if (!element.isWebElementReference(obj)) { - throw new InvalidArgumentError("Expected 'origin' to be a string or a " + - `web element reference, got: ${obj}`); - } - return origin; -}; - -/** Represents possible subtypes for a pointer input source. */ -action.PointerType = { - Mouse: "mouse", - // TODO For now, only mouse is supported - //Pen: "pen", - //Touch: "touch", -}; - -/** - * Look up a PointerType. - * - * @param {string} str - * Name of pointer type. - * - * @return {string} - * A pointer type for processing pointer parameters. - * - * @throws {InvalidArgumentError} - * If |str| is not a valid pointer type. - */ -action.PointerType.get = function (str) { - let name = capitalize(str); - assert.in(name, this, error.pprint`Unknown pointerType: ${str}`); - return this[name]; -}; - -/** - * Input state associated with current session. This is a map between input ID and - * the device state for that input source, with one entry for each active input source. - * - * Initialized in listener.js - */ -action.inputStateMap = undefined; - -/** - * List of |action.Action| associated with current session. Used to manage dispatching - * events when resetting the state of the input sources. Reset operations are assumed - * to be idempotent. - * - * Initialized in listener.js - */ -action.inputsToCancel = undefined; - -/** - * Represents device state for an input source. - */ -class InputState { - constructor() { - this.type = this.constructor.name.toLowerCase(); - } - - /** - * Check equality of this InputState object with another. - * - * @para{?} other - * Object representing an input state. - * @return {boolean} - * True if |this| has the same |type| as |other|. - */ - is(other) { - if (typeof other == "undefined") { - return false; - } - return this.type === other.type; - } - - toString() { - return `[object ${this.constructor.name}InputState]`; - } - - /** - * @param {?} obj - * Object with property |type| and optionally |parameters| or |pointerType|, - * representing an action sequence or an action item. - * - * @return {action.InputState} - * An |action.InputState| object for the type of the |actionSequence|. - * - * @throws {InvalidArgumentError} - * If |actionSequence.type| is not valid. - */ - static fromJson(obj) { - let type = obj.type; - assert.in(type, ACTIONS, error.pprint`Unknown action type: ${type}`); - let name = type == "none" ? "Null" : capitalize(type); - if (name == "Pointer") { - if (!obj.pointerType && (!obj.parameters || !obj.parameters.pointerType)) { - throw new InvalidArgumentError( - error.pprint`Expected obj to have pointerType, got: ${obj}`); - } - let pointerType = obj.pointerType || obj.parameters.pointerType; - return new action.InputState[name](pointerType); - } else { - return new action.InputState[name](); - } - } -} - -/** Possible kinds of |InputState| for supported input sources. */ -action.InputState = {}; - -/** - * Input state associated with a keyboard-type device. - */ -action.InputState.Key = class Key extends InputState { - constructor() { - super(); - this.pressed = new Set(); - this.alt = false; - this.shift = false; - this.ctrl = false; - this.meta = false; - } - - /** - * Update modifier state according to |key|. - * - * @param {string} key - * Normalized key value of a modifier key. - * @param {boolean} value - * Value to set the modifier attribute to. - * - * @throws {InvalidArgumentError} - * If |key| is not a modifier. - */ - setModState(key, value) { - if (key in MODIFIER_NAME_LOOKUP) { - this[MODIFIER_NAME_LOOKUP[key]] = value; - } else { - throw new InvalidArgumentError("Expected 'key' to be one of " + - `${Object.keys(MODIFIER_NAME_LOOKUP)}; got: ${key}`); - } - } - - /** - * Check whether |key| is pressed. - * - * @param {string} key - * Normalized key value. - * - * @return {boolean} - * True if |key| is in set of pressed keys. - */ - isPressed(key) { - return this.pressed.has(key); - } - - /** - * Add |key| to the set of pressed keys. - * - * @param {string} key - * Normalized key value. - * - * @return {boolean} - * True if |key| is in list of pressed keys. - */ - press(key) { - return this.pressed.add(key); - } - - /** - * Remove |key| from the set of pressed keys. - * - * @param {string} key - * Normalized key value. - * - * @return {boolean} - * True if |key| was present before removal, false otherwise. - */ - release(key) { - return this.pressed.delete(key); - } -}; - -/** - * Input state not associated with a specific physical device. - */ -action.InputState.Null = class Null extends InputState { - constructor() { - super(); - this.type = "none"; - } -}; - -/** - * Input state associated with a pointer-type input device. - * - * @param {string} subtype - * Kind of pointing device: mouse, pen, touch. - * - * @throws {InvalidArgumentError} - * If subtype is undefined or an invalid pointer type. - */ -action.InputState.Pointer = class Pointer extends InputState { - constructor(subtype) { - super(); - this.pressed = new Set(); - assert.defined(subtype, error.pprint`Expected subtype to be defined, got: ${subtype}`); - this.subtype = action.PointerType.get(subtype); - this.x = 0; - this.y = 0; - } - - /** - * Check whether |button| is pressed. - * - * @param {number} button - * Positive integer that refers to a mouse button. - * - * @return {boolean} - * True if |button| is in set of pressed buttons. - */ - isPressed(button) { - assert.positiveInteger(button); - return this.pressed.has(button); - } - - /** - * Add |button| to the set of pressed keys. - * - * @param {number} button - * Positive integer that refers to a mouse button. - * - * @return {Set} - * Set of pressed buttons. - */ - press(button) { - assert.positiveInteger(button); - return this.pressed.add(button); - } - - /** - * Remove |button| from the set of pressed buttons. - * - * @param {number} button - * A positive integer that refers to a mouse button. - * - * @return {boolean} - * True if |button| was present before removals, false otherwise. - */ - release(button) { - assert.positiveInteger(button); - return this.pressed.delete(button); - } -}; - -/** - * Repesents an action for dispatch. Used in |action.Chain| and |action.Sequence|. - * - * @param {string} id - * Input source ID. - * @param {string} type - * Action type: none, key, pointer. - * @param {string} subtype - * Action subtype: pause, keyUp, keyDown, pointerUp, pointerDown, pointerMove, pointerCancel. - * - * @throws {InvalidArgumentError} - * If any parameters are undefined. - */ -action.Action = class { - constructor(id, type, subtype) { - if ([id, type, subtype].includes(undefined)) { - throw new InvalidArgumentError("Missing id, type or subtype"); - } - for (let attr of [id, type, subtype]) { - assert.string(attr, error.pprint`Expected string, got: ${attr}`); - } - this.id = id; - this.type = type; - this.subtype = subtype; - }; - - toString() { - return `[action ${this.type}]`; - } - - /** - * @param {?} actionSequence - * Object representing sequence of actions from one input source. - * @param {?} actionItem - * Object representing a single action from |actionSequence|. - * - * @return {action.Action} - * An action that can be dispatched; corresponds to |actionItem|. - * - * @throws {InvalidArgumentError} - * If any |actionSequence| or |actionItem| attributes are invalid. - * @throws {UnsupportedOperationError} - * If |actionItem.type| is |pointerCancel|. - */ - static fromJson(actionSequence, actionItem) { - let type = actionSequence.type; - let id = actionSequence.id; - let subtypes = ACTIONS[type]; - if (!subtypes) { - throw new InvalidArgumentError("Unknown type: " + type); - } - let subtype = actionItem.type; - if (!subtypes.has(subtype)) { - throw new InvalidArgumentError(`Unknown subtype for ${type} action: ${subtype}`); - } - - let item = new action.Action(id, type, subtype); - if (type === "pointer") { - action.processPointerAction(id, - action.PointerParameters.fromJson(actionSequence.parameters), item); - } - - switch (item.subtype) { - case action.KeyUp: - case action.KeyDown: - let key = actionItem.value; - // TODO countGraphemes - // TODO key.value could be a single code point like "\uE012" (see rawKey) - // or "grapheme cluster" - assert.string(key, - error.pprint("Expected 'value' to be a string that represents single code point " + - `or grapheme cluster, got: ${key}`)); - item.value = key; - break; - - case action.PointerDown: - case action.PointerUp: - assert.positiveInteger(actionItem.button, - error.pprint`Expected 'button' (${actionItem.button}) to be >= 0`); - item.button = actionItem.button; - break; - - case action.PointerMove: - item.duration = actionItem.duration; - if (typeof item.duration != "undefined"){ - assert.positiveInteger(item.duration, - error.pprint`Expected 'duration' (${item.duration}) to be >= 0`); - } - item.origin = action.PointerOrigin.get(actionItem.origin); - item.x = actionItem.x; - if (typeof item.x != "undefined") { - assert.integer(item.x, error.pprint`Expected 'x' (${item.x}) to be an Integer`); - } - item.y = actionItem.y; - if (typeof item.y != "undefined") { - assert.integer(item.y, error.pprint`Expected 'y' (${item.y}) to be an Integer`); - } - break; - - case action.PointerCancel: - throw new UnsupportedOperationError(); - break; - - case action.Pause: - item.duration = actionItem.duration; - if (typeof item.duration != "undefined") { - assert.positiveInteger(item.duration, - error.pprint`Expected 'duration' (${item.duration}) to be >= 0`); - } - break; - } - - return item; - } -}; - -/** - * Represents a series of ticks, specifying which actions to perform at each tick. - */ -action.Chain = class extends Array { - toString() { - return `[chain ${super.toString()}]`; - } - - /** - * @param {Array.} actions - * Array of objects that each represent an action sequence. - * - * @return {action.Chain} - * Transpose of |actions| such that actions to be performed in a single tick - * are grouped together. - * - * @throws {InvalidArgumentError} - * If |actions| is not an Array. - */ - static fromJson(actions) { - assert.array(actions, - error.pprint`Expected 'actions' to be an Array, got: ${actions}`); - let actionsByTick = new action.Chain(); - // TODO check that each actionSequence in actions refers to a different input ID - for (let actionSequence of actions) { - let inputSourceActions = action.Sequence.fromJson(actionSequence); - for (let i = 0; i < inputSourceActions.length; i++) { - // new tick - if (actionsByTick.length < (i + 1)) { - actionsByTick.push([]); - } - actionsByTick[i].push(inputSourceActions[i]); - } - } - return actionsByTick; - } -}; - -/** - * Represents one input source action sequence; this is essentially an |Array.|. - */ -action.Sequence = class extends Array { - toString() { - return `[sequence ${super.toString()}]`; - } - - /** - * @param {?} actionSequence - * Object that represents a sequence action items for one input source. - * - * @return {action.Sequence} - * Sequence of actions that can be dispatched. - * - * @throws {InvalidArgumentError} - * If |actionSequence.id| is not a string or it's aleady mapped - * to an |action.InputState} incompatible with |actionSequence.type|. - * If |actionSequence.actions| is not an Array. - */ - static fromJson(actionSequence) { - // used here to validate 'type' in addition to InputState type below - let inputSourceState = InputState.fromJson(actionSequence); - let id = actionSequence.id; - assert.defined(id, "Expected 'id' to be defined"); - assert.string(id, error.pprint`Expected 'id' to be a string, got: ${id}`); - let actionItems = actionSequence.actions; - assert.array(actionItems, - error.pprint("Expected 'actionSequence.actions' to be an Array, " + - `got: ${actionSequence.actions}`)); - if (!action.inputStateMap.has(id)) { - action.inputStateMap.set(id, inputSourceState); - } else if (!action.inputStateMap.get(id).is(inputSourceState)) { - throw new InvalidArgumentError( - `Expected ${id} to be mapped to ${inputSourceState}, ` + - `got: ${action.inputStateMap.get(id)}`); - } - let actions = new action.Sequence(); - for (let actionItem of actionItems) { - actions.push(action.Action.fromJson(actionSequence, actionItem)); - } - return actions; - } -}; - -/** - * Represents parameters in an action for a pointer input source. - * - * @param {string=} pointerType - * Type of pointing device. If the parameter is undefined, "mouse" is used. - */ -action.PointerParameters = class { - constructor(pointerType = "mouse") { - this.pointerType = action.PointerType.get(pointerType); - } - - toString() { - return `[pointerParameters ${this.pointerType}]`; - } - - /** - * @param {?} parametersData - * Object that represents pointer parameters. - * - * @return {action.PointerParameters} - * Validated pointer paramters. - */ - static fromJson(parametersData) { - if (typeof parametersData == "undefined") { - return new action.PointerParameters(); - } else { - return new action.PointerParameters(parametersData.pointerType); - } - } -}; - -/** - * Adds |pointerType| attribute to Action |act|. Helper function - * for |action.Action.fromJson|. - * - * @param {string} id - * Input source ID. - * @param {action.PointerParams} pointerParams - * Input source pointer parameters. - * @param {action.Action} act - * Action to be updated. - * - * @throws {InvalidArgumentError} - * If |id| is already mapped to an |action.InputState| that is - * not compatible with |act.type| or |pointerParams.pointerType|. - */ -action.processPointerAction = function processPointerAction(id, pointerParams, act) { - if (action.inputStateMap.has(id) && action.inputStateMap.get(id).type !== act.type) { - throw new InvalidArgumentError( - `Expected 'id' ${id} to be mapped to InputState whose type is ` + - `${action.inputStateMap.get(id).type}, got: ${act.type}`); - } - let pointerType = pointerParams.pointerType; - if (action.inputStateMap.has(id) && action.inputStateMap.get(id).subtype !== pointerType) { - throw new InvalidArgumentError( - `Expected 'id' ${id} to be mapped to InputState whose subtype is ` + - `${action.inputStateMap.get(id).subtype}, got: ${pointerType}`); - } - act.pointerType = pointerParams.pointerType; -}; - -/** Collect properties associated with KeyboardEvent */ -action.Key = class { - constructor(rawKey) { - this.key = NORMALIZED_KEY_LOOKUP[rawKey] || rawKey; - this.code = KEY_CODE_LOOKUP[rawKey]; - this.location = KEY_LOCATION_LOOKUP[rawKey] || 0; - this.altKey = false; - this.shiftKey = false; - this.ctrlKey = false; - this.metaKey = false; - this.repeat = false; - this.isComposing = false; - // Prevent keyCode from being guessed in event.js; we don't want to use it anyway. - this.keyCode = 0; - } - - update(inputState) { - this.altKey = inputState.alt; - this.shiftKey = inputState.shift; - this.ctrlKey = inputState.ctrl; - this.metaKey = inputState.meta; - } -}; - -/** Collect properties associated with MouseEvent */ -action.Mouse = class { - constructor(type, button = 0) { - this.type = type; - assert.positiveInteger(button); - this.button = button; - this.buttons = 0; - } - - update(inputState) { - let allButtons = Array.from(inputState.pressed); - this.buttons = allButtons.reduce((a, i) => a + Math.pow(2, i), 0); - } -}; - -/** - * Dispatch a chain of actions over |chain.length| ticks. - * - * This is done by creating a Promise for each tick that resolves once all the - * Promises for individual tick-actions are resolved. The next tick's actions are - * not dispatched until the Promise for the current tick is resolved. - * - * @param {action.Chain} chain - * Actions grouped by tick; each element in |chain| is a sequence of - * actions for one tick. - * @param {element.Store} seenEls - * Element store. - * @param {?} container - * Object with |frame| attribute of type |nsIDOMWindow|. - * - * @return {Promise} - * Promise for dispatching all actions in |chain|. - */ -action.dispatch = function(chain, seenEls, container) { - let chainEvents = Task.spawn(function*() { - for (let tickActions of chain) { - yield action.dispatchTickActions( - tickActions, action.computeTickDuration(tickActions), seenEls, container); - } - }); - return chainEvents; -}; - -/** - * Dispatch sequence of actions for one tick. - * - * This creates a Promise for one tick that resolves once the Promise for each - * tick-action is resolved, which takes at least |tickDuration| milliseconds. - * The resolved set of events for each tick is followed by firing of pending DOM events. - * - * Note that the tick-actions are dispatched in order, but they may have different - * durations and therefore may not end in the same order. - * - * @param {Array.} tickActions - * List of actions for one tick. - * @param {number} tickDuration - * Duration in milliseconds of this tick. - * @param {element.Store} seenEls - * Element store. - * @param {?} container - * Object with |frame| attribute of type |nsIDOMWindow|. - * - * @return {Promise} - * Promise for dispatching all tick-actions and pending DOM events. - */ -action.dispatchTickActions = function(tickActions, tickDuration, seenEls, container) { - let pendingEvents = tickActions.map(toEvents(tickDuration, seenEls, container)); - return Promise.all(pendingEvents).then(() => flushEvents(container)); -}; - -/** - * Compute tick duration in milliseconds for a collection of actions. - * - * @param {Array.} tickActions - * List of actions for one tick. - * - * @return {number} - * Longest action duration in |tickActions| if any, or 0. - */ -action.computeTickDuration = function(tickActions) { - let max = 0; - for (let a of tickActions) { - let affectsWallClockTime = a.subtype == action.Pause || - (a.type == "pointer" && a.subtype == action.PointerMove); - if (affectsWallClockTime && a.duration) { - max = Math.max(a.duration, max); - } - } - return max; -}; - -/** - * Compute viewport coordinates of pointer target based on given origin. - * - * @param {action.Action} a - * Action that specifies pointer origin and x and y coordinates of target. - * @param {action.InputState} inputState - * Input state that specifies current x and y coordinates of pointer. - * @param {Map.=} center - * Object representing x and y coordinates of an element center-point. - * This is only used if |a.origin| is a web element reference. - * - * @return {Map.} - * x and y coordinates of pointer destination. - */ -action.computePointerDestination = function(a, inputState, center = undefined) { - let {x, y} = a; - switch (a.origin) { - case action.PointerOrigin.Viewport: - break; - case action.PointerOrigin.Pointer: - x += inputState.x; - y += inputState.y; - break; - default: - // origin represents web element - assert.defined(center); - assert.in("x", center); - assert.in("y", center); - x += center.x; - y += center.y; - } - return {"x": x, "y": y}; -}; - -/** - * Create a closure to use as a map from action definitions to Promise events. - * - * @param {number} tickDuration - * Duration in milliseconds of this tick. - * @param {element.Store} seenEls - * Element store. - * @param {?} container - * Object with |frame| attribute of type |nsIDOMWindow|. - * - * @return {function(action.Action): Promise} - * Function that takes an action and returns a Promise for dispatching - * the event that corresponds to that action. - */ -function toEvents(tickDuration, seenEls, container) { - return function (a) { - let inputState = action.inputStateMap.get(a.id); - switch (a.subtype) { - case action.KeyUp: - return dispatchKeyUp(a, inputState, container.frame); - - case action.KeyDown: - return dispatchKeyDown(a, inputState, container.frame); - - case action.PointerDown: - return dispatchPointerDown(a, inputState, container.frame); - - case action.PointerUp: - return dispatchPointerUp(a, inputState, container.frame); - - case action.PointerMove: - return dispatchPointerMove(a, inputState, tickDuration, seenEls, container); - - case action.PointerCancel: - throw new UnsupportedOperationError(); - - case action.Pause: - return dispatchPause(a, tickDuration); - } - }; -} - -/** - * Dispatch a keyDown action equivalent to pressing a key on a keyboard. - * - * @param {action.Action} a - * Action to dispatch. - * @param {action.InputState} inputState - * Input state for this action's input source. - * @param {nsIDOMWindow} win - * Current window. - * - * @return {Promise} - * Promise to dispatch at least a keydown event, and keypress if appropriate. - */ -function dispatchKeyDown(a, inputState, win) { - return new Promise(resolve => { - let keyEvent = new action.Key(a.value); - keyEvent.repeat = inputState.isPressed(keyEvent.key); - inputState.press(keyEvent.key); - if (keyEvent.key in MODIFIER_NAME_LOOKUP) { - inputState.setModState(keyEvent.key, true); - } - // Append a copy of |a| with keyUp subtype - action.inputsToCancel.push(Object.assign({}, a, {subtype: action.KeyUp})); - keyEvent.update(inputState); - event.sendKeyDown(keyEvent.key, keyEvent, win); - - resolve(); - }); -} - -/** - * Dispatch a keyUp action equivalent to releasing a key on a keyboard. - * - * @param {action.Action} a - * Action to dispatch. - * @param {action.InputState} inputState - * Input state for this action's input source. - * @param {nsIDOMWindow} win - * Current window. - * - * @return {Promise} - * Promise to dispatch a keyup event. - */ -function dispatchKeyUp(a, inputState, win) { - return new Promise(resolve => { - let keyEvent = new action.Key(a.value); - if (!inputState.isPressed(keyEvent.key)) { - resolve(); - return; - } - if (keyEvent.key in MODIFIER_NAME_LOOKUP) { - inputState.setModState(keyEvent.key, false); - } - inputState.release(keyEvent.key); - keyEvent.update(inputState); - event.sendKeyUp(keyEvent.key, keyEvent, win); - - resolve(); - }); -} - -/** - * Dispatch a pointerDown action equivalent to pressing a pointer-device - * button. - * - * @param {action.Action} a - * Action to dispatch. - * @param {action.InputState} inputState - * Input state for this action's input source. - * @param {nsIDOMWindow} win - * Current window. - * - * @return {Promise} - * Promise to dispatch at least a pointerdown event. - */ -function dispatchPointerDown(a, inputState, win) { - return new Promise(resolve => { - if (inputState.isPressed(a.button)) { - resolve(); - return; - } - inputState.press(a.button); - // Append a copy of |a| with pointerUp subtype - action.inputsToCancel.push(Object.assign({}, a, {subtype: action.PointerUp})); - switch (inputState.subtype) { - case action.PointerType.Mouse: - let mouseEvent = new action.Mouse("mousedown", a.button); - mouseEvent.update(inputState); - event.synthesizeMouseAtPoint(inputState.x, inputState.y, mouseEvent, win); - break; - case action.PointerType.Pen: - case action.PointerType.Touch: - throw new UnsupportedOperationError("Only 'mouse' pointer type is supported"); - break; - default: - throw new TypeError(`Unknown pointer type: ${inputState.subtype}`); - } - resolve(); - }); -} - -/** - * Dispatch a pointerUp action equivalent to releasing a pointer-device - * button. - * - * @param {action.Action} a - * Action to dispatch. - * @param {action.InputState} inputState - * Input state for this action's input source. - * @param {nsIDOMWindow} win - * Current window. - * - * @return {Promise} - * Promise to dispatch at least a pointerup event. - */ -function dispatchPointerUp(a, inputState, win) { - return new Promise(resolve => { - if (!inputState.isPressed(a.button)) { - resolve(); - return; - } - inputState.release(a.button); - switch (inputState.subtype) { - case action.PointerType.Mouse: - let mouseEvent = new action.Mouse("mouseup", a.button); - mouseEvent.update(inputState); - event.synthesizeMouseAtPoint(inputState.x, inputState.y, - mouseEvent, win); - break; - case action.PointerType.Pen: - case action.PointerType.Touch: - throw new UnsupportedOperationError("Only 'mouse' pointer type is supported"); - default: - throw new TypeError(`Unknown pointer type: ${inputState.subtype}`); - } - resolve(); - }); -} - -/** - * Dispatch a pointerMove action equivalent to moving pointer device in a line. - * - * If the action duration is 0, the pointer jumps immediately to the target coordinates. - * Otherwise, events are synthesized to mimic a pointer travelling in a discontinuous, - * approximately straight line, with the pointer coordinates being updated around 60 - * times per second. - * - * @param {action.Action} a - * Action to dispatch. - * @param {action.InputState} inputState - * Input state for this action's input source. - * @param {element.Store} seenEls - * Element store. - * @param {?} container - * Object with |frame| attribute of type |nsIDOMWindow|. - * - * @return {Promise} - * Promise to dispatch at least one pointermove event, as well as mousemove events - * as appropriate. - */ -function dispatchPointerMove(a, inputState, tickDuration, seenEls, container) { - const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - // interval between pointermove increments in ms, based on common vsync - const fps60 = 17; - return new Promise(resolve => { - const start = Date.now(); - const [startX, startY] = [inputState.x, inputState.y]; - let target = action.computePointerDestination(a, inputState, - getElementCenter(a.origin, seenEls, container)); - const [targetX, targetY] = [target.x, target.y]; - if (!inViewPort(targetX, targetY, container.frame)) { - throw new MoveTargetOutOfBoundsError( - `(${targetX}, ${targetY}) is out of bounds of viewport ` + - `width (${container.frame.innerWidth}) and height (${container.frame.innerHeight})`); - } - - const duration = typeof a.duration == "undefined" ? tickDuration : a.duration; - if (duration === 0) { - // move pointer to destination in one step - performOnePointerMove(inputState, targetX, targetY, container.frame); - resolve(); - return; - } - - const distanceX = targetX - startX; - const distanceY = targetY - startY; - const ONE_SHOT = Ci.nsITimer.TYPE_ONE_SHOT; - let intermediatePointerEvents = Task.spawn(function* () { - // wait |fps60| ms before performing first incremental pointer move - yield new Promise(resolveTimer => - timer.initWithCallback(resolveTimer, fps60, ONE_SHOT) - ); - let durationRatio = Math.floor(Date.now() - start) / duration; - const epsilon = fps60 / duration / 10; - while ((1 - durationRatio) > epsilon) { - let x = Math.floor(durationRatio * distanceX + startX); - let y = Math.floor(durationRatio * distanceY + startY); - performOnePointerMove(inputState, x, y, container.frame); - // wait |fps60| ms before performing next pointer move - yield new Promise(resolveTimer => - timer.initWithCallback(resolveTimer, fps60, ONE_SHOT)); - durationRatio = Math.floor(Date.now() - start) / duration; - } - }); - // perform last pointer move after all incremental moves are resolved and - // durationRatio is close enough to 1 - intermediatePointerEvents.then(() => { - performOnePointerMove(inputState, targetX, targetY, container.frame); - resolve(); - }); - - }); -} - -function performOnePointerMove(inputState, targetX, targetY, win) { - if (targetX == inputState.x && targetY == inputState.y) { - return; - } - switch (inputState.subtype) { - case action.PointerType.Mouse: - let mouseEvent = new action.Mouse("mousemove"); - mouseEvent.update(inputState); - //TODO both pointermove (if available) and mousemove - event.synthesizeMouseAtPoint(targetX, targetY, mouseEvent, win); - break; - case action.PointerType.Pen: - case action.PointerType.Touch: - throw new UnsupportedOperationError("Only 'mouse' pointer type is supported"); - default: - throw new TypeError(`Unknown pointer type: ${inputState.subtype}`); - } - inputState.x = targetX; - inputState.y = targetY; -} - -/** - * Dispatch a pause action equivalent waiting for |a.duration| milliseconds, or a - * default time interval of |tickDuration|. - * - * @param {action.Action} a - * Action to dispatch. - * @param {number} tickDuration - * Duration in milliseconds of this tick. - * - * @return {Promise} - * Promise that is resolved after the specified time interval. - */ -function dispatchPause(a, tickDuration) { - const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - let duration = typeof a.duration == "undefined" ? tickDuration : a.duration; - return new Promise(resolve => - timer.initWithCallback(resolve, duration, Ci.nsITimer.TYPE_ONE_SHOT) - ); -} - -// helpers -/** - * Force any pending DOM events to fire. - * - * @param {?} container - * Object with |frame| attribute of type |nsIDOMWindow|. - * - * @return {Promise} - * Promise to flush DOM events. - */ -function flushEvents(container) { - return new Promise(resolve => container.frame.requestAnimationFrame(resolve)); -} - -function capitalize(str) { - assert.string(str); - return str.charAt(0).toUpperCase() + str.slice(1); -} - -function inViewPort(x, y, win) { - assert.number(x, `Expected x to be finite number`); - assert.number(y, `Expected y to be finite number`); - // Viewport includes scrollbars if rendered. - return !(x < 0 || y < 0 || x > win.innerWidth || y > win.innerHeight); -} - -function getElementCenter(elementReference, seenEls, container) { - if (element.isWebElementReference(elementReference)) { - let uuid = elementReference[element.Key] || elementReference[element.LegacyKey]; - let el = seenEls.get(uuid, container); - return element.coordinates(el); - } -} diff --git a/testing/marionette/addon.js b/testing/marionette/addon.js deleted file mode 100644 index d2ead6fb28..0000000000 --- a/testing/marionette/addon.js +++ /dev/null @@ -1,104 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/AddonManager.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); - -Cu.import("chrome://marionette/content/error.js"); - -this.EXPORTED_SYMBOLS = ["addon"]; - -this.addon = {}; - -// from https://developer.mozilla.org/en-US/Add-ons/Add-on_Manager/AddonManager#AddonInstall_errors -addon.Errors = { - [-1]: "ERROR_NETWORK_FAILURE: A network error occured.", - [-2]: "ERROR_INCORECT_HASH: The downloaded file did not match the expected hash.", - [-3]: "ERROR_CORRUPT_FILE: The file appears to be corrupt.", - [-4]: "ERROR_FILE_ACCESS: There was an error accessing the filesystem.", - [-5]: "ERROR_SIGNEDSTATE_REQUIRED: The addon must be signed and isn't.", -}; - -function lookupError(code) { - let msg = addon.Errors[code]; - return new UnknownError(msg); -} - -/** - * Install a Firefox addon. - * - * If the addon is restartless, it can be used right away. Otherwise a - * restart is required. - * - * Temporary addons will automatically be uninstalled on shutdown and - * do not need to be signed, though they must be restartless. - * - * @param {string} path - * Full path to the extension package archive. - * @param {boolean=} temporary - * True to install the addon temporarily, false (default) otherwise. - * - * @return {Promise: string} - * Addon ID. - * - * @throws {UnknownError} - * If there is a problem installing the addon. - */ -addon.install = function (path, temporary = false) { - return new Promise((resolve, reject) => { - let file = new FileUtils.File(path); - - let listener = { - onInstallEnded: function (install, addon) { - resolve(addon.id); - }, - - onInstallFailed: function (install) { - reject(lookupError(install.error)); - }, - - onInstalled: function (addon) { - AddonManager.removeAddonListener(listener); - resolve(addon.id); - } - }; - - if (!temporary) { - AddonManager.getInstallForFile(file, function (aInstall) { - if (aInstall.error !== 0) { - reject(lookupError(aInstall.error)); - } - aInstall.addListener(listener); - aInstall.install(); - }); - } else { - AddonManager.addAddonListener(listener); - AddonManager.installTemporaryAddon(file); - } - }); -}; - -/** - * Uninstall a Firefox addon. - * - * If the addon is restartless it will be uninstalled right away. - * Otherwise, Firefox must be restarted for the change to take effect. - * - * @param {string} id - * ID of the addon to uninstall. - * - * @return {Promise} - */ -addon.uninstall = function (id) { - return new Promise(resolve => { - AddonManager.getAddonByID(id, function (addon) { - addon.uninstall(); - resolve(); - }); - }); -}; diff --git a/testing/marionette/assert.js b/testing/marionette/assert.js deleted file mode 100644 index b2d228d0ef..0000000000 --- a/testing/marionette/assert.js +++ /dev/null @@ -1,322 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/AppConstants.jsm"); -Cu.import("resource://gre/modules/Preferences.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -Cu.import("chrome://marionette/content/error.js"); - -this.EXPORTED_SYMBOLS = ["assert"]; - -const isFennec = () => AppConstants.platform == "android"; -const isB2G = () => false; -const isFirefox = () => Services.appinfo.name == "Firefox"; - -/** Shorthands for common assertions made in Marionette. */ -this.assert = {}; - -/** - * Asserts that Marionette has a session. - * - * @param {GeckoDriver} driver - * Marionette driver instance. - * @param {string=} msg - * Custom error message. - * - * @return {string} - * Session ID. - * - * @throws {InvalidSessionIDError} - * If |driver| does not have a session ID. - */ -assert.session = function (driver, msg = "") { - assert.that(sessionID => sessionID, - msg, InvalidSessionIDError)(driver.sessionId); - return driver.sessionId; -}; - -/** - * Asserts that the current browser is Firefox Desktop. - * - * @param {string=} msg - * Custom error message. - * - * @throws {UnsupportedOperationError} - * If current browser is not Firefox. - */ -assert.firefox = function (msg = "") { - msg = msg || "Only supported in Firefox"; - assert.that(isFirefox, msg, UnsupportedOperationError)(); -}; - -/** - * Asserts that the current browser is Fennec, or Firefox for Android. - * - * @param {string=} msg - * Custom error message. - * - * @throws {UnsupportedOperationError} - * If current browser is not Fennec. - */ -assert.fennec = function (msg = "") { - msg = msg || "Only supported in Fennec"; - assert.that(isFennec, msg, UnsupportedOperationError)(); -}; - -/** - * Asserts that the current browser is B2G. - * - * @param {string=} msg - * Custom error message. - * - * @throws {UnsupportedOperationError} - * If the current browser is not B2G. - */ -assert.b2g = function (msg = "") { - msg = msg || "Only supported in B2G"; - assert.that(isB2G, msg, UnsupportedOperationError)(); -}; - -/** - * Asserts that the current |context| is content. - * - * @param {string} context - * Context to test. - * @param {string=} msg - * Custom error message. - * - * @return {string} - * |context| is returned unaltered. - * - * @throws {UnsupportedOperationError} - * If |context| is not content. - */ -assert.content = function (context, msg = "") { - msg = msg || "Only supported in content context"; - assert.that(c => c.toString() == "content", msg, UnsupportedOperationError)(context); -}; - -/** - * Asserts that the current browser is a mobile browser, that is either - * B2G or Fennec. - * - * @param {string=} msg - * Custom error message. - * - * @throws {UnsupportedOperationError} - * If the current browser is not B2G or Fennec. - */ -assert.mobile = function (msg = "") { - msg = msg || "Only supported in Fennec or B2G"; - assert.that(() => isFennec() || isB2G(), msg, UnsupportedOperationError)(); -}; - -/** - * Asserts that |obj| is defined. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {?} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not defined. - */ -assert.defined = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be defined`; - return assert.that(o => typeof o != "undefined", msg)(obj); -}; - -/** - * Asserts that |obj| is a finite number. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {number} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not a number. - */ -assert.number = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be finite number`; - return assert.that(Number.isFinite, msg)(obj); -}; - -/** - * Asserts that |obj| is an integer. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {number} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not an integer. - */ -assert.integer = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be an integer`; - return assert.that(Number.isInteger, msg)(obj); -}; - -/** - * Asserts that |obj| is a positive integer. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {number} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not a positive integer. - */ -assert.positiveInteger = function (obj, msg = "") { - assert.integer(obj, msg); - msg = msg || error.pprint`Expected ${obj} to be >= 0`; - return assert.that(n => n >= 0, msg)(obj); -}; - -/** - * Asserts that |obj| is a boolean. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {boolean} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not a boolean. - */ -assert.boolean = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be boolean`; - return assert.that(b => typeof b == "boolean", msg)(obj); -}; - -/** - * Asserts that |obj| is a string. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {string} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not a string. - */ -assert.string = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be a string`; - return assert.that(s => typeof s == "string", msg)(obj); -}; - -/** - * Asserts that |obj| is an object. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {Object} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not an object. - */ -assert.object = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be an object`; - return assert.that(o => - Object.prototype.toString.call(o) == "[object Object]", msg)(obj); -}; - -/** - * Asserts that |prop| is in |obj|. - * - * @param {?} prop - * Own property to test if is in |obj|. - * @param {?} obj - * Object. - * @param {string=} msg - * Custom error message. - * - * @return {?} - * Value of |obj|'s own property |prop|. - * - * @throws {InvalidArgumentError} - * If |prop| is not in |obj|, or |obj| is not an object. - */ -assert.in = function (prop, obj, msg = "") { - assert.object(obj, msg); - msg = msg || error.pprint`Expected ${prop} in ${obj}`; - assert.that(p => obj.hasOwnProperty(p), msg)(prop); - return obj[prop]; -}; - -/** - * Asserts that |obj| is an Array. - * - * @param {?} obj - * Value to test. - * @param {string=} msg - * Custom error message. - * - * @return {Object} - * |obj| is returned unaltered. - * - * @throws {InvalidArgumentError} - * If |obj| is not an Array. - */ -assert.array = function (obj, msg = "") { - msg = msg || error.pprint`Expected ${obj} to be an Array`; - return assert.that(Array.isArray, msg)(obj); -}; - -/** - * Returns a function that is used to assert the |predicate|. - * - * @param {function(?): boolean} predicate - * Evaluated on calling the return value of this function. If its - * return value of the inner function is false, |error| is thrown - * with |message|. - * @param {string=} message - * Custom error message. - * @param {Error=} error - * Custom error type by its class. - * - * @return {function(?): ?} - * Function that takes and returns the passed in value unaltered, and - * which may throw |error| with |message| if |predicate| evaluates - * to false. - */ -assert.that = function ( - predicate, message = "", error = InvalidArgumentError) { - return obj => { - if (!predicate(obj)) { - throw new error(message); - } - return obj; - }; -}; diff --git a/testing/marionette/atom.js b/testing/marionette/atom.js deleted file mode 100644 index 369e5c44ce..0000000000 --- a/testing/marionette/atom.js +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2011-2014 Software Freedom Conservancy -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -this.EXPORTED_SYMBOLS = ["atom"]; - -this.atom = {}; - -atom.clearElement = function (element, window){return function(){function g(a){throw a;}var h=void 0,i=!0,k=null,l=!1;function n(a){return function(){return this[a]}}function o(a){return function(){return a}}var p,q=this; -function aa(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; -else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function r(a){return a!==h}function ba(a){var b=aa(a);return"array"==b||"object"==b&&"number"==typeof a.length}function t(a){return"string"==typeof a}function w(a){return"function"==aa(a)}function ca(a){a=aa(a);return"object"==a||"array"==a||"function"==a}var da="closure_uid_"+Math.floor(2147483648*Math.random()).toString(36),ea=0,fa=Date.now||function(){return+new Date}; -function x(a,b){function c(){}c.prototype=b.prototype;a.$=b.prototype;a.prototype=new c};function ga(a,b){for(var c=1;c")&&(a=a.replace(ma,">"));-1!=a.indexOf('"')&&(a=a.replace(na,"""));return a}var ka=/&/g,la=//g,na=/\"/g,ja=/[&<>\"]/; -function oa(a,b){for(var c=0,d=ha(""+a).split("."),e=ha(""+b).split("."),f=Math.max(d.length,e.length),j=0;0==c&&j(0==v[1].length?0:parseInt(v[1],10))?1:0)||((0==u[2].length)<(0==v[2].length)?-1:(0== -u[2].length)>(0==v[2].length)?1:0)||(u[2]v[2]?1:0)}while(0==c)}return c}var pa=2147483648*Math.random()|0,qa={};function ra(a){return qa[a]||(qa[a]=(""+a).replace(/\-([a-z])/g,function (a,c){return c.toUpperCase()}))};var sa,ta;function ua(){return q.navigator?q.navigator.userAgent:k}var va,wa=q.navigator;va=wa&&wa.platform||"";sa=-1!=va.indexOf("Mac");ta=-1!=va.indexOf("Win");var xa=-1!=va.indexOf("Linux"),ya,za="",Aa=/rv\:([^\);]+)(\)|;)/.exec(ua());ya=za=Aa?Aa[1]:"";var Ba={};var Ca=window;function Da(a,b){for(var c in a)b.call(h,a[c],c,a)}function Ea(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};function y(a,b){this.code=a;this.message=b||"";this.name=Fa[a]||Fa[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}x(y,Error); -var Fa={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"}; -y.prototype.toString=function(){return"["+this.name+"] "+this.message};function Ga(a){this.stack=Error().stack||"";a&&(this.message=""+a)}x(Ga,Error);Ga.prototype.name="CustomError";function Ha(a,b){b.unshift(a);Ga.call(this,ga.apply(k,b));b.shift()}x(Ha,Ga);Ha.prototype.name="AssertionError";function Ia(a,b,c){if(!a){var d=Array.prototype.slice.call(arguments,2),e="Assertion failed";if(b)var e=e+(": "+b),f=d;g(new Ha(""+e,f||[]))}}function Ja(a,b){g(new Ha("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1)))};function z(a){return a[a.length-1]}var Ka=Array.prototype;function A(a,b){if(t(a))return!t(b)||1!=b.length?-1:a.indexOf(b,0);for(var c=0;cc?k:t(a)?a.charAt(c):a[c]}function Qa(a){return Ka.concat.apply(Ka,arguments)} -function Ra(a){if("array"==aa(a))return Qa(a);for(var b=[],c=0,d=a.length;c=arguments.length?Ka.slice.call(a,b):Ka.slice.call(a,b,c)};var Ta;Ba["1.9.1"]||(Ba["1.9.1"]=0<=oa(ya,"1.9.1"));function Ua(a,b){var c;c=(c=a.className)&&"function"==typeof c.split?c.split(/\s+/):[];var d=Sa(arguments,1),e;e=c;for(var f=0,j=0;j=a.length&&g(I);if(b in a)return a[b++];b++}};return c}g(Error("Not implemented"))};function K(a,b,c,d,e){this.o=!!b;a&&L(this,a,d);this.depth=e!=h?e:this.q||0;this.o&&(this.depth*=-1);this.za=!c}x(K,J);p=K.prototype;p.p=k;p.q=0;p.ha=l;function L(a,b,c,d){if(a.p=b)a.q="number"==typeof c?c:1!=a.p.nodeType?0:a.o?-1:1;"number"==typeof d&&(a.depth=d)} -p.next=function(){var a;if(this.ha){(!this.p||this.za&&0==this.depth)&&g(I);a=this.p;var b=this.o?-1:1;if(this.q==b){var c=this.o?a.lastChild:a.firstChild;c?L(this,c):L(this,a,-1*b)}else(c=this.o?a.previousSibling:a.nextSibling)?L(this,c):L(this,a.parentNode,-1*b);this.depth+=this.q*(this.o?-1:1)}else this.ha=i;(a=this.p)||g(I);return a}; -p.splice=function (a){var b=this.p,c=this.o?1:-1;this.q==c&&(this.q=-1*c,this.depth+=this.q*(this.o?-1:1));this.o=!this.o;K.prototype.next.call(this);this.o=!this.o;for(var c=ba(arguments[0])?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);bb(b)};function tb(a,b,c,d){K.call(this,a,b,c,k,d)}x(tb,K);tb.prototype.next=function(){do tb.$.next.call(this);while(-1==this.q);return this.p};function ub(a,b){var c=D(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,k))?c[b]||c.getPropertyValue(b):""}function vb(a,b){return ub(a,b)||(a.currentStyle?a.currentStyle[b]:k)||a.style&&a.style[b]} -function wb(a){for(var b=D(a),c=vb(a,"position"),d="fixed"==c||"absolute"==c,a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=vb(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return k} -function xb(a){var b=new B;if(1==a.nodeType)if(a.getBoundingClientRect)a=a.getBoundingClientRect(),b.x=a.left,b.y=a.top;else{var c=mb(Wa(a));var d,e=D(a),f=vb(a,"position"),j=e.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==f&&(d=e.getBoxObjectFor(a))&&(0>d.screenX||0>d.screenY),f=new B(0,0),m=(e?9==e.nodeType?e:D(e):document).documentElement;if(a!=m)if(a.getBoundingClientRect)d=a.getBoundingClientRect(),a=mb(Wa(e)),f.x=d.left+a.x,f.y=d.top+a.y;else if(e.getBoxObjectFor&&!j)d=e.getBoxObjectFor(a), -a=e.getBoxObjectFor(m),f.x=d.screenX-a.screenX,f.y=d.screenY-a.screenY;else{d=a;do f.x+=d.offsetLeft,f.y+=d.offsetTop,d!=a&&(f.x+=d.clientLeft||0,f.y+=d.clientTop||0),d=d.offsetParent;while(d&&d!=a);for(d=a;(d=wb(d))&&d!=e.body&&d!=m;)f.x-=d.scrollLeft,f.y-=d.scrollTop}b.x=f.x-c.x;b.y=f.y-c.y}else c=w(a.pa),d=a,a.targetTouches?d=a.targetTouches[0]:c&&a.pa().targetTouches&&(d=a.pa().targetTouches[0]),b.x=d.clientX,b.y=d.clientY;return b} -function yb(a){var b=a.offsetWidth,c=a.offsetHeight;return!r(b)&&a.getBoundingClientRect?(a=a.getBoundingClientRect(),new Va(a.right-a.left,a.bottom-a.top)):new Va(b,c)};function M(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}var zb={"class":"className",readonly:"readOnly"},Ab=["checked","disabled","draggable","hidden"];function Bb(a,b){var c=zb[b]||b,d=a[c];if(!r(d)&&0<=A(Ab,c))return l;if(c="value"==b)if(c=M(a,"OPTION")){var e;c=b.toLowerCase();if(a.hasAttribute)e=a.hasAttribute(c);else try{e=a.attributes[c].specified}catch(f){e=l}c=!e}c&&(d=[],kb(a,d,l),d=d.join(""));return d} -var Cb="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(","),Db="BUTTON,INPUT,OPTGROUP,OPTION,SELECT,TEXTAREA".split(","); -function Eb(a){var b=a.tagName.toUpperCase();return!(0<=A(Db,b))?i:Bb(a,"disabled")?l:a.parentNode&&1==a.parentNode.nodeType&&"OPTGROUP"==b||"OPTION"==b?Eb(a.parentNode):i}var Fb="text,search,tel,url,email,password,number".split(",");function Gb(a){return M(a,"TEXTAREA")?i:M(a,"INPUT")?0<=A(Fb,a.type.toLowerCase()):Hb(a)?i:l} -function Hb(a){function b(a){return"inherit"==a.contentEditable?(a=Ib(a))?b(a):l:"true"==a.contentEditable}return!r(a.contentEditable)?l:r(a.isContentEditable)?a.isContentEditable:b(a)}function Ib(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return M(a)?a:k}function Jb(a,b){b=ra(b);return ub(a,b)||Kb(a,b)} -function Kb(a,b){var c=a.currentStyle||a.style,d=c[b];!r(d)&&w(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?r(d)?d:k:(c=Ib(a))?Kb(c,b):k}function Lb(a){if(w(a.getBBox))try{var b=a.getBBox();if(b)return b}catch(c){}if("none"!=vb(a,"display"))a=yb(a);else{var b=a.style,d=b.display,e=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=yb(a);b.display=d;b.position=f;b.visibility=e}return a} -function Mb(a,b){function c(a){if("none"==Jb(a,"display"))return l;a=Ib(a);return!a||c(a)}function d(a){var b=Lb(a);return 0=c.length&&g(I);var j=c[b++];return a?j:d[":"+j]}};return j};function jc(a){this.n=new hc;a&&this.aa(a)}function kc(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+(a[da]||(a[da]=++ea)):b.substr(0,1)+a}p=jc.prototype;p.add=function (a){this.n.set(kc(a),a)};p.aa=function (a){for(var a=gc(a),b=a.length,c=0;c");R(191,"/","?");R(192,"`","~");R(219,"[","{");R(220,"\\","|");R(221,"]","}");R({c:59,e:186,opera:59},";",":");R(222,"'",'"');lc.prototype.X=function (a){return this.Ha.contains(a)};function oc(a){return pc(a||arguments.callee.caller,[])} -function pc(a,b){var c=[];if(0<=A(b,a))c.push("[...circular reference...]");else if(a&&50>b.length){c.push(qc(a)+"(");for(var d=a.arguments,e=0;e=xc(this).value){a=this.Ca(a,b,c);b="log:"+a.Fa;q.console&&(q.console.timeStamp?q.console.timeStamp(b):q.console.markTimeline&&q.console.markTimeline(b));q.msWriteProfilerMark&&q.msWriteProfilerMark(b);for(b=this;b;){var c=b,d=a;if(c.ra)for(var e=0,f=h;f=c.ra[e];e++)f(d);b=b.getParent()}}}; -S.prototype.Ca=function (a,b,c){var d=new sc(a,""+b,this.Ga);if(c){d.oa=c;var e;var f=arguments.callee.caller;try{var j;var m;c:{for(var s=["window","location","href"],O=q,E;E=s.shift();)if(O[E]!=k)O=O[E];else{m=k;break c}m=O}if(t(c))j={message:c,name:"Unknown error",lineNumber:"Not available",fileName:m,stack:"Not available"};else{var u,v,s=l;try{u=c.lineNumber||c.Ma||"Not available"}catch(md){u="Not available",s=i}try{v=c.fileName||c.filename||c.sourceURL||m}catch(nd){v="Not available",s=i}j=s|| -!c.lineNumber||!c.fileName||!c.stack?{message:c.message,name:c.name,lineNumber:u,fileName:v,stack:c.stack||"Not available"}:c}e="Message: "+ia(j.message)+'\nUrl: '+j.fileName+"\nLine: "+j.lineNumber+"\n\nBrowser stack:\n"+ia(j.stack+"-> ")+"[end]\n\nJS stack traversal:\n"+ia(oc(f)+"-> ")}catch(kd){e="Exception trying to expose exception! You win, we lose. "+kd}d.na=e}return d};var yc={},zc=k; -function Ac(a){zc||(zc=new S(""),yc[""]=zc,zc.va(wc));var b;if(!(b=yc[a])){b=new S(a);var c=a.lastIndexOf("."),d=a.substr(c+1),c=Ac(a.substr(0,c));c.ba||(c.ba={});c.ba[d]=b;b.Y=c;yc[a]=b}return b};function Bc(){}x(Bc,function(){});Ac("goog.dom.SavedRange");x(function (a){this.Ja="goog_"+pa++;this.Aa="goog_"+pa++;this.la=Wa(a.ea());a.R(this.la.da("SPAN",{id:this.Ja}),this.la.da("SPAN",{id:this.Aa}))},Bc);function T(){}function Cc(a){if(a.getSelection)return a.getSelection();var a=a.document,b=a.selection;if(b){try{var c=b.createRange();if(c.parentElement){if(c.parentElement().document!=a)return k}else if(!c.length||c.item(0).document!=a)return k}catch(d){return k}return b}return k}function Dc(a){for(var b=[],c=0,d=a.D();c=this.l(d,1,0):0<=this.l(d,0,0)&&0>=this.l(d,1,1)}catch(e){g(e)}};Hc.prototype.containsNode=function (a,b){return this.u(Fc(a),b)};Hc.prototype.r=function(){return new Gc(this.b(),this.j(),this.g(),this.k())};function Ic(a){this.a=a}x(Ic,Hc);p=Ic.prototype;p.C=function(){return this.a.commonAncestorContainer};p.b=function(){return this.a.startContainer};p.j=function(){return this.a.startOffset};p.g=function(){return this.a.endContainer};p.k=function(){return this.a.endOffset};p.l=function (a,b,c){return this.a.compareBoundaryPoints(1==c?1==b?q.Range.START_TO_START:q.Range.START_TO_END:1==b?q.Range.END_TO_START:q.Range.END_TO_END,a)};p.isCollapsed=function(){return this.a.collapsed}; -p.select=function (a){this.Z(F(D(this.b())).getSelection(),a)};p.Z=function (a){a.removeAllRanges();a.addRange(this.a)};p.insertNode=function (a,b){var c=this.a.cloneRange();c.collapse(b);c.insertNode(a);c.detach();return a}; -p.R=function (a,b){var c=F(D(this.b()));if(c=(c=Cc(c||window))&&Jc(c))var d=c.b(),e=c.g(),f=c.j(),j=c.k();var m=this.a.cloneRange(),s=this.a.cloneRange();m.collapse(l);s.collapse(i);m.insertNode(b);s.insertNode(a);m.detach();s.detach();if(c){if(d.nodeType==C)for(;f>d.length;){f-=d.length;do d=d.nextSibling;while(d==a||d==b)}if(e.nodeType==C)for(;j>e.length;){j-=e.length;do e=e.nextSibling;while(e==a||e==b)}c=new Kc;c.G=Lc(d,f,e,j);"BR"==d.tagName&&(m=d.parentNode,f=A(m.childNodes,d),d=m);"BR"==e.tagName&& -(m=e.parentNode,j=A(m.childNodes,e),e=m);c.G?(c.f=e,c.i=j,c.d=d,c.h=f):(c.f=d,c.i=f,c.d=e,c.h=j);c.select()}};p.collapse=function (a){this.a.collapse(a)};function W(a){this.a=a}x(W,Ic);function Fc(a){var b=D(a).createRange();if(a.nodeType==C)b.setStart(a,0),b.setEnd(a,a.length);else if(X(a)){for(var c,d=a;(c=d.firstChild)&&X(c);)d=c;b.setStart(d,0);for(d=a;(c=d.lastChild)&&X(c);)d=c;b.setEnd(d,1==d.nodeType?d.childNodes.length:d.length)}else c=a.parentNode,a=A(c.childNodes,a),b.setStart(c,a),b.setEnd(c,a+1);return new W(b)} -W.prototype.Z=function (a,b){var c=b?this.g():this.b(),d=b?this.k():this.j(),e=b?this.b():this.g(),f=b?this.j():this.k();a.collapse(c,d);(c!=e||d!=f)&&a.extend(e,f)};function Mc(a){this.a=a}x(Mc,Hc);Ac("goog.dom.browserrange.IeRange");function Nc(a){var b=D(a).body.createTextRange();if(1==a.nodeType)b.moveToElementText(a),X(a)&&!a.childNodes.length&&b.collapse(l);else{for(var c=0,d=a;d=d.previousSibling;){var e=d.nodeType;if(e==C)c+=d.length;else if(1==e){b.moveToElementText(d);break}}d||b.moveToElementText(a.parentNode);b.collapse(!d);c&&b.move("character",c);b.moveEnd("character",a.length)}return b}p=Mc.prototype;p.O=k;p.f=k;p.d=k;p.i=-1;p.h=-1; -p.s=function(){this.O=this.f=this.d=k;this.i=this.h=-1}; -p.C=function(){if(!this.O){var a=this.a.text,b=this.a.duplicate(),c=a.replace(/ +$/,"");(c=a.length-c.length)&&b.moveEnd("character",-c);c=b.parentElement();b=b.htmlText.replace(/(\r\n|\r|\n)+/g," ").length;if(this.isCollapsed()&&0c.outerHTML.replace(/(\r\n|\r|\n)+/g," ").length;)c=c.parentNode;for(;1==c.childNodes.length&&c.innerText==(c.firstChild.nodeType==C?c.firstChild.nodeValue:c.firstChild.innerText)&&X(c.firstChild);)c=c.firstChild;0==a.length&&(c=Oc(this,c));this.O= -c}return this.O};function Oc(a,b){for(var c=b.childNodes,d=0,e=c.length;d=a.l(j,1,0):a.a.inRange(j))return Oc(a,f)}}return b}p.b=function(){this.f||(this.f=Pc(this,1),this.isCollapsed()&&(this.d=this.f));return this.f};p.j=function(){0>this.i&&(this.i=Qc(this,1),this.isCollapsed()&&(this.h=this.i));return this.i}; -p.g=function(){if(this.isCollapsed())return this.b();this.d||(this.d=Pc(this,0));return this.d};p.k=function(){if(this.isCollapsed())return this.j();0>this.h&&(this.h=Qc(this,0),this.isCollapsed()&&(this.i=this.h));return this.h};p.l=function (a,b,c){return this.a.compareEndPoints((1==b?"Start":"End")+"To"+(1==c?"Start":"End"),a)}; -function Pc(a,b,c){c=c||a.C();if(!c||!c.firstChild)return c;for(var d=1==b,e=0,f=c.childNodes.length;ea.l(E,1,0)&&0(0==F[1].length?0:parseInt(F[1],10))?1:0)||((0==E[2].length)<(0==F[2].length)?-1:(0== -E[2].length)>(0==F[2].length)?1:0)||(E[2]F[2]?1:0)}while(0==v)}p["1.9.1"]=0<=v};var G={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},H={IMG:" ",BR:"\n"};function I(a,c,b){if(!(a.nodeName in G))if(3==a.nodeType)b?c.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):c.push(a.nodeValue);else if(a.nodeName in H)c.push(H[a.nodeName]);else for(a=a.firstChild;a;)I(a,c,b),a=a.nextSibling};(function(){var a=h.Components;if(!a)return g;try{if(!a.classes)return g}catch(c){return g}var b=a.classes,a=a.interfaces;b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();var J="StopIteration"in h?h.StopIteration:Error("StopIteration");function K(){}K.prototype.next=function(){throw J;};function L(a,c,b,d,e){this.a=!!c;a&&M(this,a,d);this.depth=void 0!=e?e:this.c||0;this.a&&(this.depth*=-1);this.e=!b}j(L,K);L.prototype.b=f;L.prototype.c=0;L.prototype.d=g;function M(a,c,b){if(a.b=c)a.c="number"==typeof b?b:1!=a.b.nodeType?0:a.a?-1:1} -L.prototype.next=function(){var a;if(this.d){if(!this.b||this.e&&0==this.depth)throw J;a=this.b;var c=this.a?-1:1;if(this.c==c){var b=this.a?a.lastChild:a.firstChild;b?M(this,b):M(this,a,-1*c)}else(b=this.a?a.previousSibling:a.nextSibling)?M(this,b):M(this,a.parentNode,-1*c);this.depth+=this.c*(this.a?-1:1)}else this.d=!0;a=this.b;if(!this.b)throw J;return a}; -L.prototype.splice=function (a){var c=this.b,b=this.a?1:-1;this.c==b&&(this.c=-1*b,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;L.prototype.next.call(this);this.a=!this.a;for(var b=arguments[0],d=i(b),b="array"==d||"object"==d&&"number"==typeof b.length?arguments[0]:arguments,d=b.length-1;0<=d;d--)c.parentNode&&c.parentNode.insertBefore(b[d],c.nextSibling);c&&c.parentNode&&c.parentNode.removeChild(c)};function N(a,c,b,d){L.call(this,a,c,b,f,d)}j(N,L);N.prototype.next=function(){do N.f.next.call(this);while(-1==this.c);return this.b};function O(a,c){return!!a&&1==a.nodeType&&(!c||a.tagName.toUpperCase()==c)}function P(a){return O(a,"OPTION")?!0:O(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):g}var Q={"class":"className",readonly:"readOnly"},R=["checked","disabled","draggable","hidden"]; -function S(a,c){var b=Q[c]||c,d=a[b];if(void 0===d&&0<=u(R,b))return g;if(b="value"==c)if(b=O(a,"OPTION")){var e;b=c.toLowerCase();if(a.hasAttribute)e=a.hasAttribute(b);else try{e=a.attributes[b].specified}catch(Y){e=g}b=!e}b&&(d=[],I(a,d,g),d=d.join(""));return d}var T="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(","); -function U(a,c){if(8==a.nodeType)return f;c=c.toLowerCase();if("style"==c){var b=l(a.style.cssText).toLowerCase();return b=";"==b.charAt(b.length-1)?b:b+";"}b=a.getAttributeNode(c);return!b?f:0<=u(T,c)?"true":b.specified?b.value:f};function V(a,c){var b=f,d=c.toLowerCase();if("style"==c.toLowerCase()){if((b=a.style)&&"string"!=typeof b)b=b.cssText;return b}if("selected"==d||"checked"==d&&P(a)){if(!P(a))throw new q(15,"Element is not selectable");var e="selected",d=a.type&&a.type.toLowerCase();if("checkbox"==d||"radio"==d)e="checked";return S(a,e)?"true":f}b=O(a,"A");if(O(a,"IMG")&&"src"==d||b&&"href"==d)return(b=U(a,d))&&(b=S(a,d)),b;try{e=S(a,c)}catch(Y){}if(!(d=e==f))d=i(e),d="object"==d||"array"==d||"function"==d;b=d?U(a, -c):e;return b!=f?b.toString():f}var W=["_"],X=h;!(W[0]in X)&&X.execScript&&X.execScript("var "+W[0]);for(var Z;W.length&&(Z=W.shift());)!W.length&&void 0!==V?X[Z]=V:X=X[Z]?X[Z]:X[Z]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);} - -atom.getElementText = function (element, window){return function(){var g=void 0,h=!0,i=null,j=!1,k=this; -function l(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; -else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function m(a){return"string"==typeof a}function n(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function o(a){var b=a.length-1;return 0<=b&&a.indexOf(" ",b)==b}function aa(a,b){for(var c=1;c(0==H[1].length?0:parseInt(H[1],10))?1:0)||((0==G[2].length)<(0==H[2].length)?-1: -(0==G[2].length)>(0==H[2].length)?1:0)||(G[2]H[2]?1:0)}while(0==C)}v["1.9.1"]=0<=C};function I(a,b){this.x=a!==g?a:0;this.y=b!==g?b:0}I.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function J(a,b){this.width=a;this.height=b}J.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};var K=3;function L(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function la(a,b){var c=[];return M(a,b,c,h)?c[0]:g}function M(a,b,c,d){if(a!=i)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||M(a,b,c,d))return h;a=a.nextSibling}return j}function ma(a,b){for(var a=a.parentNode,c=0;a;){if(b(a))return a;a=a.parentNode;c++}return i}function N(a){this.g=a||k.document||document} -function na(a){var b=a.g,a="CSS1Compat"==b.compatMode?b.documentElement:b.body,b=b.parentWindow||b.defaultView;return new I(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)};var oa=function(){var a={i:"http://www.w3.org/2000/svg"};return function (b){return a[b]||i}}(); -function pa(a,b){var c=function(){var c;a:{var e=L(b);if(e.implementation.hasFeature("XPath","3.0")){try{var f=e.createNSResolver?e.createNSResolver(e.documentElement):oa;c=e.evaluate(a,b,f,9,i);break a}catch(r){if("NS_ERROR_ILLEGAL_VALUE"!=r.name)throw new w(32,"Unable to locate an element with the xpath expression "+a+" because of the following error:\n"+r);}c=g}else c=i}return c?c.singleNodeValue||i:b.selectSingleNode?(c=L(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectSingleNode(a)): -i}();if(c!==i&&(!c||1!=c.nodeType))throw new w(32,'The result of the xpath expression "'+a+'" is: '+c+". It should be an element.");return c};(function(){var a=k.Components;if(!a)return j;try{if(!a.classes)return j}catch(b){return j}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return h})();var P="StopIteration"in k?k.StopIteration:Error("StopIteration");function qa(){}qa.prototype.next=function(){throw P;};function Q(a,b,c,d,e){this.a=!!b;a&&R(this,a,d);this.depth=e!=g?e:this.c||0;this.a&&(this.depth*=-1);this.f=!c}n(Q,qa);Q.prototype.b=i;Q.prototype.c=0;Q.prototype.e=j;function R(a,b,c){if(a.b=b)a.c="number"==typeof c?c:1!=a.b.nodeType?0:a.a?-1:1} -Q.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&0==this.depth)throw P;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?R(this,c):R(this,a,-1*b)}else(c=this.a?a.previousSibling:a.nextSibling)?R(this,c):R(this,a.parentNode,-1*b);this.depth+=this.c*(this.a?-1:1)}else this.e=h;a=this.b;if(!this.b)throw P;return a}; -Q.prototype.splice=function (a){var b=this.b,c=this.a?1:-1;this.c==c&&(this.c=-1*c,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;Q.prototype.next.call(this);this.a=!this.a;for(var c=arguments[0],d=l(c),c="array"==d||"object"==d&&"number"==typeof c.length?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);b&&b.parentNode&&b.parentNode.removeChild(b)};function S(a,b,c,d){Q.call(this,a,b,c,i,d)}n(S,Q);S.prototype.next=function(){do S.h.next.call(this);while(-1==this.c);return this.b};function ra(a,b){var c=L(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,i))?c[b]||c.getPropertyValue(b):""}function T(a,b){return ra(a,b)||(a.currentStyle?a.currentStyle[b]:i)||a.style&&a.style[b]} -function sa(a){for(var b=L(a),c=T(a,"position"),d="fixed"==c||"absolute"==c,a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=T(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return i} -function ta(a){var b=new I;if(1==a.nodeType)if(a.getBoundingClientRect)a=a.getBoundingClientRect(),b.x=a.left,b.y=a.top;else{var c=na(a?new N(L(a)):B||(B=new N));var d,e=L(a),f=T(a,"position"),r=e.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==f&&(d=e.getBoxObjectFor(a))&&(0>d.screenX||0>d.screenY),f=new I(0,0),t=(e?9==e.nodeType?e:L(e):document).documentElement;if(a!=t)if(a.getBoundingClientRect)d=a.getBoundingClientRect(),a=na(e?new N(L(e)):B||(B=new N)),f.x=d.left+a.x,f.y=d.top+a.y;else if(e.getBoxObjectFor&& -!r)d=e.getBoxObjectFor(a),a=e.getBoxObjectFor(t),f.x=d.screenX-a.screenX,f.y=d.screenY-a.screenY;else{d=a;do f.x+=d.offsetLeft,f.y+=d.offsetTop,d!=a&&(f.x+=d.clientLeft||0,f.y+=d.clientTop||0),d=d.offsetParent;while(d&&d!=a);for(d=a;(d=sa(d))&&d!=e.body&&d!=t;)f.x-=d.scrollLeft,f.y-=d.scrollTop}b.x=f.x-c.x;b.y=f.y-c.y}else c="function"==l(a.d),d=a,a.targetTouches?d=a.targetTouches[0]:c&&a.d().targetTouches&&(d=a.d().targetTouches[0]),b.x=d.clientX,b.y=d.clientY;return b} -function ua(a){var b=a.offsetWidth,c=a.offsetHeight;return b===g&&a.getBoundingClientRect?(a=a.getBoundingClientRect(),new J(a.right-a.left,a.bottom-a.top)):new J(b,c)};function U(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}var va="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(","); -function V(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return U(a)?a:i}function W(a,b){b=ba(b);return ra(a,b)||wa(a,b)}function wa(a,b){var c=a.currentStyle||a.style,d=c[b];d===g&&"function"==l(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?d!==g?d:i:(c=V(a))?wa(c,b):i} -function xa(a){if("function"==l(a.getBBox))try{var b=a.getBBox();if(b)return b}catch(c){}if("none"!=T(a,"display"))a=ua(a);else{var b=a.style,d=b.display,e=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=ua(a);b.display=d;b.position=f;b.visibility=e}return a} -function X(a,b){function c(a){if("none"==W(a,"display"))return j;a=V(a);return!a||c(a)}function d(a){var b=xa(a);return 0(0==B[1].length? -0:parseInt(B[1],10))?1:0)||((0==A[2].length)<(0==B[2].length)?-1:(0==A[2].length)>(0==B[2].length)?1:0)||(A[2]B[2]?1:0)}while(0==q)}k["1.9.1"]=0<=q};(function(){var a=e.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(c){return!1}var b=a.classes,a=a.interfaces;b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function C(a,c,b,d,y){this.b=!!c;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=y?y:this.c||0;this.b&&(this.depth*=-1)}f(C,function(){});C.prototype.a=null;C.prototype.c=0;f(function (a,c,b,d){C.call(this,a,c,0,null,d)},C);var D={"class":"className",readonly:"readOnly"},E=["checked","disabled","draggable","hidden"],F="BUTTON,INPUT,OPTGROUP,OPTION,SELECT,TEXTAREA".split(",");function G(a){var c=a.tagName.toUpperCase();if(p(F,c)){var b;b=D.disabled||"disabled";var d=a[b];b=void 0===d&&p(E,b)?!1:d;a=b?!1:a.parentNode&&1==a.parentNode.nodeType&&"OPTGROUP"==c||"OPTION"==c?G(a.parentNode):!0}else a=!0;return a};var H=G,I=["_"],J=e;!(I[0]in J)&&J.execScript&&J.execScript("var "+I[0]);for(var K;I.length&&(K=I.shift());)!I.length&&void 0!==H?J[K]=H:J=J[K]?J[K]:J[K]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);} - -atom.isElementSelected = function (element, window){return function(){var f=!1,g=this;function h(a,b){function c(){}c.prototype=b.prototype;a.d=b.prototype;a.prototype=new c};function i(a,b){for(var c=1;c(0==C[1].length? -0:parseInt(C[1],10))?1:0)||((0==B[2].length)<(0==C[2].length)?-1:(0==B[2].length)>(0==C[2].length)?1:0)||(B[2]C[2]?1:0)}while(0==s)}n["1.9.1"]=0<=s};var D={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},E={IMG:" ",BR:"\n"};function F(a,b,c){if(!(a.nodeName in D))if(3==a.nodeType)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in E)b.push(E[a.nodeName]);else for(a=a.firstChild;a;)F(a,b,c),a=a.nextSibling};(function(){var a=g.Components;if(!a)return f;try{if(!a.classes)return f}catch(b){return f}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function G(a,b,c,d,e){this.b=!!b;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=e?e:this.c||0;this.b&&(this.depth*=-1)}h(G,function(){});G.prototype.a=null;G.prototype.c=0;h(function (a,b,c,d){G.call(this,a,b,0,null,d)},G);function H(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function I(a){return H(a,"OPTION")?!0:H(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):f}var J={"class":"className",readonly:"readOnly"},K=["checked","disabled","draggable","hidden"];function L(a){if(I(a)){if(!I(a))throw new o(15,"Element is not selectable");var b="selected",c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";var c=b,d=J[c]||c,b=a[d],e;if(e=void 0===b){b:if("string"==typeof K)d="string"!=typeof d||1!=d.length?-1:K.indexOf(d,0);else{for(e=0;e(0==v[1].length? -0:parseInt(v[1],10))?1:0)||((0==l[2].length)<(0==v[2].length)?-1:(0==l[2].length)>(0==v[2].length)?1:0)||(l[2]v[2]?1:0)}while(0==b)}return b}function aa(a){return String(a).replace(/\-([a-z])/g,function (a,c){return c.toUpperCase()})};var s=Array.prototype;function t(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e=arguments.length?s.slice.call(a,b):s.slice.call(a,b,c)};var u={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400", -darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc", -ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a", -lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1", -moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57", -seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};var fa="background-color border-top-color border-right-color border-bottom-color border-left-color color outline-color".split(" "),ga=/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/;function ha(a){if(!x.test(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(ga,"#$1$1$2$2$3$3"));return a.toLowerCase()}var x=/^#(?:[0-9a-f]{3}){1,2}$/i,ia=/^(?:rgba)?\((\d{1,3}),\s?(\d{1,3}),\s?(\d{1,3}),\s?(0|1|0\.\d*)\)$/i; -function ja(a){var b=a.match(ia);if(b){a=Number(b[1]);var c=Number(b[2]),d=Number(b[3]),b=Number(b[4]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=d&&255>=d&&0<=b&&1>=b)return[a,c,d,b]}return[]}var ka=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;function la(a){var b=a.match(ka);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};function y(a,b){this.code=a;this.state=z[a]||ma;this.message=b||"";var c=this.state.replace(/((?:^|\s+)[a-z])/g,function (a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}(function(){var a=Error;function b(){}b.prototype=a.prototype;y.I=a.prototype;y.prototype=new b})(); -var ma="unknown error",z={15:"element not selectable",11:"element not visible",31:"ime engine activation failed",30:"ime not available",24:"invalid cookie domain",29:"invalid element coordinates",12:"invalid element state",32:"invalid selector",51:"invalid selector",52:"invalid selector",17:"javascript error",405:"unsupported operation",34:"move target out of bounds",27:"no such alert",7:"no such element",8:"no such frame",23:"no such window",28:"script timeout",33:"session not created",10:"stale element reference", -0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a} -function qa(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?ra(a,b):!c&&E(e,b)?-1*sa(a,b):!d&&E(f,a)?sa(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=F(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0); -return c.compareBoundaryPoints(k.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||k.document||document} -function ua(a){var b=a.p;a="CSS1Compat"==b.compatMode?b.documentElement:b.body;b=b.parentWindow||b.defaultView;return new C(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}G.prototype.contains=E;function H(a){var b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b?"":b);if("string"!=typeof b)if(9==c||1==c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b="";a;){do 1!=a.nodeType&&(b+=a.nodeValue),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return""+b} -function I(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d){return!1}return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}function J(a,b,c,d,e){return va.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)} -function va(a,b,c,d,e){b.getElementsByName&&d&&"name"==c?(b=b.getElementsByName(d),t(b,function (b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),t(b,function (b){b.className==d&&a.matches(b)&&e.add(b)})):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName()),t(b,function (a){I(a,c,d)&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)I(b,c,d)&&a.matches(b)&&e.add(b);return e};function K(){this.d=this.c=null;this.g=0}function xa(a){this.m=a;this.next=this.i=null}K.prototype.unshift=function (a){a=new xa(a);a.next=this.c;this.d?this.c.i=a:this.c=this.d=a;this.c=a;this.g++};K.prototype.add=function (a){a=new xa(a);a.i=this.d;this.c?this.d.next=a:this.c=this.d=a;this.d=a;this.g++};function ya(a){return(a=a.c)?a.m:null}function L(a){return new za(a,!1)}function za(a,b){this.F=a;this.j=(this.n=b)?a.d:a.c;this.r=null} -za.prototype.next=function(){var a=this.j;if(null==a)return null;var b=this.r=a;this.j=this.n?a.i:a.next;return b.m};function M(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate(d);var f;if(b instanceof K&&c instanceof K){e=L(b);for(d=e.next();d;d=e.next())for(b=L(c),f=b.next();f;f=b.next())if(a(H(d),H(f)))return!0;return!1}if(b instanceof K||c instanceof K){b instanceof K?e=b:(e=c,c=b);e=L(e);b=typeof c;for(d=e.next();d;d=e.next()){switch(b){case "number":d=+H(d);break;case "boolean":d=!!H(d);break;case "string":d=H(d);break;default:throw Error("Illegal primitive type for comparison.");}if(a(d,c))return!0}return!1}return e? -"boolean"==typeof b||"boolean"==typeof c?a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}function Aa(a,b,c,d){this.s=a;this.H=b;this.o=c;this.q=d}Aa.prototype.toString=function(){return this.s};var Ba={};function N(a,b,c,d){if(a in Ba)throw Error("Binary operator already created: "+a);a=new Aa(a,b,c,d);Ba[a.toString()]=a}N("div",6,1,function (a,b,c){return a.b(c)/b.b(c)});N("mod",6,1,function (a,b,c){return a.b(c)%b.b(c)});N("*",6,1,function (a,b,c){return a.b(c)*b.b(c)}); -N("+",5,1,function (a,b,c){return a.b(c)+b.b(c)});N("-",5,1,function (a,b,c){return a.b(c)-b.b(c)});N("<",4,2,function (a,b,c){return M(function (a,b){return a",4,2,function (a,b,c){return M(function (a,b){return a>b},a,b,c)});N("<=",4,2,function (a,b,c){return M(function (a,b){return a<=b},a,b,c)});N(">=",4,2,function (a,b,c){return M(function (a,b){return a>=b},a,b,c)});N("=",3,2,function (a,b,c){return M(function (a,b){return a==b},a,b,c,!0)}); -N("!=",3,2,function (a,b,c){return M(function (a,b){return a!=b},a,b,c,!0)});N("and",2,2,function (a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function (a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,g,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=g;this.w=void 0!==w?w:g;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,g,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,g,w)}O("boolean",2,!1,!1,function (a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function (a,b){return Math.ceil(b.b(a))},1); -O("concat",3,!1,!1,function (a,b){var c=ea(arguments,1);return ba(c,function (b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function (a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,h(!1),0);O("floor",1,!1,!1,function (a,b){return Math.floor(b.b(a))},1); -O("id",4,!1,!1,function (a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function (a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function (a){f.add(a)});return f},1);O("lang",2,!1,!1,h(!1),1);O("last",1,!0,!1,function (a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function (a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0); -O("name",3,!1,!0,function (a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,h(""),0,1,!0);O("normalize-space",3,!1,!0,function (a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function (a,b){return!b.f(a)},1);O("number",1,!1,!0,function (a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function (a){return a.v()},0);O("round",1,!1,!1,function (a,b){return Math.round(b.b(a))},1); -O("starts-with",2,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);return 0==b.lastIndexOf(a,0)},2);O("string",3,!1,!0,function (a,b){return b?b.a(a):H(a.e())},0,1);O("string-length",1,!1,!0,function (a,b){return(b?b.a(a):H(a.e())).length},0,1); -O("substring",3,!1,!1,function (a,b,c,d){c=c.b(a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?d.b(a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=b.a(a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);O("substring-after",3,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2); -O("substring-before",3,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);O("sum",1,!1,!1,function (a,b){for(var c=L(b.evaluate(a)),d=0,e=c.next();e;e=c.next())d+=+H(e);return d},1,1,!0);O("translate",3,!1,!1,function (a,b,c,d){b=b.a(a);c=c.a(a);var e=d.a(a);a=[];for(d=0;d=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height}; -Q.prototype.ceil=function(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};Q.prototype.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this}; -Q.prototype.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};function Ia(a,b){var c=F(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,null))?c[b]||c.getPropertyValue(b)||"":""}function R(a,b){return Ia(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style&&a.style[b]}function Ja(a){var b;try{b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,bottom:0}}return b} -function Ka(a){var b=F(a),c=R(a,"position"),d="fixed"==c||"absolute"==c;for(a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=R(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return null} -function La(a){if(1==a.nodeType){var b;if(a.getBoundingClientRect)b=Ja(a),b=new C(b.left,b.top);else{b=ua(a?new G(F(a)):B||(B=new G));var c,d=F(a),e=R(a,"position"),f=d.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==e&&(c=d.getBoxObjectFor(a))&&(0>c.screenX||0>c.screenY),e=new C(0,0),g=(d?F(d):document).documentElement;if(a!=g)if(a.getBoundingClientRect)c=Ja(a),d=ua(d?new G(F(d)):B||(B=new G)),e.x=c.left+d.x,e.y=c.top+d.y;else if(d.getBoxObjectFor&&!f)c=d.getBoxObjectFor(a),d=d.getBoxObjectFor(g), -e.x=c.screenX-d.screenX,e.y=c.screenY-d.screenY;else{c=a;do e.x+=c.offsetLeft,e.y+=c.offsetTop,c!=a&&(e.x+=c.clientLeft||0,e.y+=c.clientTop||0),c=c.offsetParent;while(c&&c!=a);for(c=a;(c=Ka(c))&&c!=d.body&&c!=g;)e.x-=c.scrollLeft,e.y-=c.scrollTop}b=new C(e.x-b.x,e.y-b.y)}A[12]||(A[12]=0<=q(12))?a=b:((c=R(a,"-moz-transform"))||(c=R(a,"transform")),a=c?(a=c.match(Ma))?new C(parseFloat(a[1]),parseFloat(a[2])):new C(0,0):new C(0,0),a=new C(b.x+a.x,b.y+a.y));return a}b="function"==m(a.k);c=a;a.targetTouches? -c=a.targetTouches[0]:b&&a.k().targetTouches&&(c=a.k().targetTouches[0]);return new C(c.clientX,c.clientY)}var Ma=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function S(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function T(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return S(a)?a:null} -function U(a,b){var c=aa(b);if("float"==c||"cssFloat"==c||"styleFloat"==c)c="cssFloat";c=Ia(a,c)||Na(a,c);if(null===c)c=null;else if(da(fa,b)&&(x.test("#"==c.charAt(0)?c:"#"+c)||la(c).length||u&&u[c.toLowerCase()]||ja(c).length)){var d=ja(c);if(!d.length){a:if(d=la(c),!d.length){d=(d=u[c.toLowerCase()])?d:"#"==c.charAt(0)?c:"#"+c;if(x.test(d)&&(d=ha(d),d=ha(d),d=[parseInt(d.substr(1,2),16),parseInt(d.substr(3,2),16),parseInt(d.substr(5,2),16)],d.length))break a;d=[]}3==d.length&&d.push(1)}c=4!=d.length? -c:"rgba("+d.join(", ")+")"}return c}function Na(a,b){var c=a.currentStyle||a.style,d=c[b];void 0===d&&"function"==m(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?void 0!==d?d:null:(c=T(a))?Na(c,b):null} -function V(a,b){function c(a){if("none"==U(a,"display"))return!1;a=T(a);return!a||c(a)}function d(a){if(a.hasAttribute){if(a.hasAttribute("hidden"))return!1}else return!0;a=T(a);return!a||d(a)}function e(a){var b=W(a);return 0=p.left+p.width,p=d.top>=p.top+p.height;if(l&&"hidden"==e.x||p&&"hidden"==e.y)return X;if(l&&"visible"!=e.x||p&&"visible"!=e.y)return Qa(a)==X?X:"scroll"}return"none"} -function W(a){var b=Oa(a);if(b)return b.rect;if("function"==m(a.getBBox))try{var c=a.getBBox();return new Q(c.x,c.y,c.width,c.height)}catch(d){if("NS_ERROR_FAILURE"===d.name||-1!=d.message.indexOf("Component returned failure code: 0x80004005"))return new Q(0,0,0,0);throw d;}else{if(S(a,"HTML"))return a=((F(a)?F(a).parentWindow||F(a).defaultView:window)||window).document,a="CSS1Compat"==a.compatMode?a.documentElement:a.body,a=new D(a.clientWidth,a.clientHeight),new Q(0,0,a.width,a.height);b=La(a); -return new Q(b.x,b.y,a.offsetWidth,a.offsetHeight)}} -function Oa(a){var b=S(a,"MAP");if(!b&&!S(a,"AREA"))return null;var c=b?a:S(a.parentNode,"MAP")?a.parentNode:null,d=null,e=null;if(c&&c.name&&(d=Ha('/descendant::*[@usemap = "#'+c.name+'"]',F(c)))&&(e=W(d),!b&&"default"!=a.shape.toLowerCase())){var f=Ra(a);a=Math.min(Math.max(f.left,0),e.width);b=Math.min(Math.max(f.top,0),e.height);c=Math.min(f.width,e.width-a);f=Math.min(f.height,e.height-b);e=new Q(a+e.left,b+e.top,c,f)}return{l:d,rect:e||new Q(0,0,0,0)}} -function Ra(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4==a.length){var b=a[0],c=a[1];return new Q(b,c,a[2]-b,a[3]-c)}if("circle"==b&&3==a.length)return b=a[2],new Q(a[0]-b,a[1]-b,2*b,2*b);if("poly"==b&&2 for the specified tab. - * - * @param {} tab - * The tab whose browser needs to be returned. - * - * @return {} - * The linked browser for the tab or null if no browser can be found. - */ -browser.getBrowserForTab = function (tab) { - if ("browser" in tab) { - // Fennec - return tab.browser; - - } else if ("linkedBrowser" in tab) { - // Firefox - return tab.linkedBrowser; - - } else { - return null; - } -}; - -/** - * Return the tab browser for the specified chrome window. - * - * @param {nsIDOMWindow} win - * The window whose tabbrowser needs to be accessed. - * - * @return {} - * Tab browser or null if it's not a browser window. - */ -browser.getTabBrowser = function (win) { - if ("BrowserApp" in win) { - // Fennec - return win.BrowserApp; - - } else if ("gBrowser" in win) { - // Firefox - return win.gBrowser; - - } else { - return null; - } -}; - -/** - * Creates a browsing context wrapper. - * - * Browsing contexts handle interactions with the browser, according to - * the current environment (desktop, B2G, Fennec, &c). - * - * @param {nsIDOMWindow} win - * The window whose browser needs to be accessed. - * @param {GeckoDriver} driver - * Reference to the driver the browser is attached to. - */ -browser.Context = class { - - /** - * @param {} win - * Frame that is expected to contain the view of the web document. - * @param {GeckoDriver} driver - * Reference to driver instance. - */ - constructor(win, driver) { - this.window = win; - this.driver = driver; - - // In Firefox this is (not !) - // and BrowserApp in Fennec - this.tabBrowser = browser.getTabBrowser(win); - - this.knownFrames = []; - - // Used in B2G to identify the homescreen content page - this.mainContentId = null; - - // Used to set curFrameId upon new session - this.newSession = true; - - this.seenEls = new element.Store(); - - // A reference to the tab corresponding to the current window handle, if any. - // Specifically, this.tab refers to the last tab that Marionette switched - // to in this browser window. Note that this may not equal the currently - // selected tab. For example, if Marionette switches to tab A, and then - // clicks on a button that opens a new tab B in the same browser window, - // this.tab will still point to tab A, despite tab B being the currently - // selected tab. - this.tab = null; - this.pendingCommands = []; - - // We should have one frame.Manager per browser.Context so that we - // can handle modals in each . - this.frameManager = new frame.Manager(driver); - this.frameRegsPending = 0; - - // register all message listeners - this.frameManager.addMessageManagerListeners(driver.mm); - this.getIdForBrowser = driver.getIdForBrowser.bind(driver); - this.updateIdForBrowser = driver.updateIdForBrowser.bind(driver); - this._curFrameId = null; - this._browserWasRemote = null; - this._hasRemotenessChange = false; - } - - /** - * The current frame ID is managed per browser element on desktop in - * case the ID needs to be refreshed. The currently selected window is - * identified by a tab. - */ - get curFrameId() { - let rv = null; - if (this.driver.appName == "B2G") { - rv = this._curFrameId; - } else if (this.tab) { - rv = this.getIdForBrowser(browser.getBrowserForTab(this.tab)); - } - return rv; - } - - set curFrameId(id) { - if (this.driver.appName != "Firefox") { - this._curFrameId = id; - } - } - - /** - * Retrieves the current tabmodal UI object. According to the browser - * associated with the currently selected tab. - */ - getTabModalUI() { - let br = browser.getBrowserForTab(this.tab); - if (!br.hasAttribute("tabmodalPromptShowing")) { - return null; - } - - // The modal is a direct sibling of the browser element. - // See tabbrowser.xml's getTabModalPromptBox. - let modals = br.parentNode.getElementsByTagNameNS( - XUL_NS, "tabmodalprompt"); - return modals[0].ui; - } - - /** - * Close the current window. - * - * @return {Promise} - * A promise which is resolved when the current window has been closed. - */ - closeWindow() { - return new Promise(resolve => { - this.window.addEventListener("unload", ev => { - resolve(); - }, {once: true}); - this.window.close(); - }); - } - - /** Called when we start a session with this browser. */ - startSession(newSession, win, callback) { - callback(win, newSession); - } - - /** - * Close the current tab. - * - * @return {Promise} - * A promise which is resolved when the current tab has been closed. - * - * @throws UnsupportedOperationError - * If tab handling for the current application isn't supported. - */ - closeTab() { - // If the current window is not a browser then close it directly. Do the - // same if only one remaining tab is open, or no tab selected at all. - if (!this.tabBrowser || this.tabBrowser.tabs.length === 1 || !this.tab) { - return this.closeWindow(); - } - - return new Promise((resolve, reject) => { - if (this.tabBrowser.closeTab) { - // Fennec - this.tabBrowser.deck.addEventListener("TabClose", ev => { - resolve(); - }, {once: true}); - this.tabBrowser.closeTab(this.tab); - - } else if (this.tabBrowser.removeTab) { - // Firefox - this.tab.addEventListener("TabClose", ev => { - resolve(); - }, {once: true}); - this.tabBrowser.removeTab(this.tab); - - } else { - reject(new UnsupportedOperationError( - `closeTab() not supported in ${this.driver.appName}`)); - } - }); - } - - /** - * Opens a tab with given URI. - * - * @param {string} uri - * URI to open. - */ - addTab(uri) { - return this.tabBrowser.addTab(uri, true); - } - - /** - * Set the current tab and update remoteness tracking if a tabbrowser is available. - * - * @param {number=} index - * Tab index to switch to. If the parameter is undefined, - * the currently selected tab will be used. - * @param {nsIDOMWindow=} win - * Switch to this window before selecting the tab. - * @param {boolean=} focus - * A boolean value which determins whether to focus - * the window. Defaults to true. - * - * @throws UnsupportedOperationError - * If tab handling for the current application isn't supported. - */ - switchToTab(index, win, focus = true) { - if (win) { - this.window = win; - this.tabBrowser = browser.getTabBrowser(win); - } - - if (!this.tabBrowser) { - return; - } - - if (typeof index == "undefined") { - this.tab = this.tabBrowser.selectedTab; - } else { - this.tab = this.tabBrowser.tabs[index]; - - if (focus) { - if (this.tabBrowser.selectTab) { - // Fennec - this.tabBrowser.selectTab(this.tab); - - } else if ("selectedTab" in this.tabBrowser) { - // Firefox - this.tabBrowser.selectedTab = this.tab; - - } else { - throw new UnsupportedOperationError("switchToTab() not supported"); - } - } - } - - if (this.driver.appName == "Firefox") { - this._browserWasRemote = browser.getBrowserForTab(this.tab).isRemoteBrowser; - this._hasRemotenessChange = false; - } - } - - /** - * Registers a new frame, and sets its current frame id to this frame - * if it is not already assigned, and if a) we already have a session - * or b) we're starting a new session and it is the right start frame. - * - * @param {string} uid - * Frame uid for use by Marionette. - * @param the XUL that was the target of the originating message. - */ - register(uid, target) { - let remotenessChange = this.hasRemotenessChange(); - if (this.curFrameId === null || remotenessChange) { - if (this.tabBrowser) { - // If we're setting up a new session on Firefox, we only process the - // registration for this frame if it belongs to the current tab. - if (!this.tab) { - this.switchToTab(); - } - - if (target == browser.getBrowserForTab(this.tab)) { - this.updateIdForBrowser(browser.getBrowserForTab(this.tab), uid); - this.mainContentId = uid; - } - } else { - this._curFrameId = uid; - this.mainContentId = uid; - } - } - - // used to delete sessions - this.knownFrames.push(uid); - return remotenessChange; - } - - /** - * When navigating between pages results in changing a browser's - * process, we need to take measures not to lose contact with a listener - * script. This function does the necessary bookkeeping. - */ - hasRemotenessChange() { - // None of these checks are relevant on b2g or if we don't have a tab yet, - // and may not apply on Fennec. - if (this.driver.appName != "Firefox" || - this.tab === null || - browser.getBrowserForTab(this.tab) === null) { - return false; - } - - if (this._hasRemotenessChange) { - return true; - } - - let currentIsRemote = browser.getBrowserForTab(this.tab).isRemoteBrowser; - this._hasRemotenessChange = this._browserWasRemote !== currentIsRemote; - this._browserWasRemote = currentIsRemote; - return this._hasRemotenessChange; - } - - /** - * Flushes any pending commands queued when a remoteness change is being - * processed and mark this remotenessUpdate as complete. - */ - flushPendingCommands() { - if (!this._hasRemotenessChange) { - return; - } - - this._hasRemotenessChange = false; - this.pendingCommands.forEach(cb => cb()); - this.pendingCommands = []; - } - - /** - * This function intercepts commands interacting with content and queues - * or executes them as needed. - * - * No commands interacting with content are safe to process until - * the new listener script is loaded and registers itself. - * This occurs when a command whose effect is asynchronous (such - * as goBack) results in a remoteness change and new commands - * are subsequently posted to the server. - */ - executeWhenReady(cb) { - if (this.hasRemotenessChange()) { - this.pendingCommands.push(cb); - } else { - cb(); - } - } - - /** - * Returns the position of the OS window. - */ - get position() { - return { - x: this.window.screenX, - y: this.window.screenY, - }; - } - -}; - -/** - * The window storage is used to save outer window IDs mapped to weak - * references of Window objects. - * - * Usage: - * - * let wins = new browser.Windows(); - * wins.set(browser.outerWindowID, window); - * - * ... - * - * let win = wins.get(browser.outerWindowID); - * - */ -browser.Windows = class extends Map { - - /** - * Save a weak reference to the Window object. - * - * @param {string} id - * Outer window ID. - * @param {Window} win - * Window object to save. - * - * @return {browser.Windows} - * Instance of self. - */ - set(id, win) { - let wref = Cu.getWeakReference(win); - super.set(id, wref); - return this; - } - - /** - * Get the window object stored by provided |id|. - * - * @param {string} id - * Outer window ID. - * - * @return {Window} - * Saved window object, or |undefined| if no window is stored by - * provided |id|. - */ - get(id) { - let wref = super.get(id); - if (wref) { - return wref.get(); - } - } - -}; diff --git a/testing/marionette/capture.js b/testing/marionette/capture.js deleted file mode 100644 index 274d205675..0000000000 --- a/testing/marionette/capture.js +++ /dev/null @@ -1,193 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {utils: Cu} = Components; -Cu.importGlobalProperties(["crypto"]); - -this.EXPORTED_SYMBOLS = ["capture"]; - -const CONTEXT_2D = "2d"; -const BG_COLOUR = "rgb(255,255,255)"; -const PNG_MIME = "image/png"; -const XHTML_NS = "http://www.w3.org/1999/xhtml"; - -/** Provides primitives to capture screenshots. */ -this.capture = {}; - -capture.Format = { - Base64: 0, - Hash: 1, -}; - -/** - * Take a screenshot of a single element. - * - * @param {Node} node - * The node to take a screenshot of. - * @param {Array.=} highlights - * Optional array of nodes, around which a border will be marked to - * highlight them in the screenshot. - * - * @return {HTMLCanvasElement} - * The canvas element where the element has been painted on. - */ -capture.element = function (node, highlights = []) { - let win = node.ownerDocument.defaultView; - let rect = node.getBoundingClientRect(); - - return capture.canvas( - win, - rect.left, - rect.top, - rect.width, - rect.height, - highlights); -}; - -/** - * Take a screenshot of the window's viewport by taking into account - * the current offsets. - * - * @param {DOMWindow} win - * The DOM window providing the document element to capture, - * and the offsets for the viewport. - * @param {Array.=} highlights - * Optional array of nodes, around which a border will be marked to - * highlight them in the screenshot. - * - * @return {HTMLCanvasElement} - * The canvas element where the viewport has been painted on. - */ -capture.viewport = function (win, highlights = []) { - let rootNode = win.document.documentElement; - - return capture.canvas( - win, - win.pageXOffset, - win.pageYOffset, - rootNode.clientWidth, - rootNode.clientHeight, - highlights); -}; - -/** - * Low-level interface to draw a rectangle off the framebuffer. - * - * @param {DOMWindow} win - * The DOM window used for the framebuffer, and providing the interfaces - * for creating an HTMLCanvasElement. - * @param {number} left - * The left, X axis offset of the rectangle. - * @param {number} top - * The top, Y axis offset of the rectangle. - * @param {number} width - * The width dimension of the rectangle to paint. - * @param {number} height - * The height dimension of the rectangle to paint. - * @param {Array.=} highlights - * Optional array of nodes, around which a border will be marked to - * highlight them in the screenshot. - * - * @return {HTMLCanvasElement} - * The canvas on which the selection from the window's framebuffer - * has been painted on. - */ -capture.canvas = function (win, left, top, width, height, highlights = []) { - let scale = win.devicePixelRatio; - - let canvas = win.document.createElementNS(XHTML_NS, "canvas"); - canvas.width = width * scale; - canvas.height = height * scale; - - let ctx = canvas.getContext(CONTEXT_2D); - let flags = ctx.DRAWWINDOW_DRAW_CARET; - // Disabled in bug 1243415 for webplatform-test failures due to out of view elements. - // Needs https://github.com/w3c/web-platform-tests/issues/4383 fixed. - // ctx.DRAWWINDOW_DRAW_VIEW; - // Bug 1009762 - Crash in [@ mozilla::gl::ReadPixelsIntoDataSurface] - // ctx.DRAWWINDOW_USE_WIDGET_LAYERS; - - ctx.scale(scale, scale); - ctx.drawWindow(win, left, top, width, height, BG_COLOUR, flags); - ctx = capture.highlight_(ctx, highlights, top, left); - - return canvas; -}; - -capture.highlight_ = function (context, highlights, top = 0, left = 0) { - if (!highlights) { - return; - } - - context.lineWidth = "2"; - context.strokeStyle = "red"; - context.save(); - - for (let el of highlights) { - let rect = el.getBoundingClientRect(); - let oy = -top; - let ox = -left; - - context.strokeRect( - rect.left + ox, - rect.top + oy, - rect.width, - rect.height); - } - - return context; -}; - -/** - * Encode the contents of an HTMLCanvasElement to a Base64 encoded string. - * - * @param {HTMLCanvasElement} canvas - * The canvas to encode. - * - * @return {string} - * A Base64 encoded string. - */ -capture.toBase64 = function (canvas) { - let u = canvas.toDataURL(PNG_MIME); - return u.substring(u.indexOf(",") + 1); -}; - -/** -* Hash the contents of an HTMLCanvasElement to a SHA-256 hex digest. -* -* @param {HTMLCanvasElement} canvas -* The canvas to encode. -* -* @return {string} -* A hex digest of the SHA-256 hash of the base64 encoded string. -*/ -capture.toHash = function (canvas) { - let u = capture.toBase64(canvas); - let buffer = new TextEncoder("utf-8").encode(u); - return crypto.subtle.digest("SHA-256", buffer).then(hash => hex(hash)); -}; - -/** -* Convert buffer into to hex. -* -* @param {ArrayBuffer} buffer -* The buffer containing the data to convert to hex. -* -* @return {string} -* A hex digest of the input buffer. -*/ -function hex(buffer) { - let hexCodes = []; - let view = new DataView(buffer); - for (let i = 0; i < view.byteLength; i += 4) { - let value = view.getUint32(i); - let stringValue = value.toString(16); - let padding = '00000000'; - let paddedValue = (padding + stringValue).slice(-padding.length); - hexCodes.push(paddedValue); - } - return hexCodes.join(""); -}; \ No newline at end of file diff --git a/testing/marionette/cert.js b/testing/marionette/cert.js deleted file mode 100644 index e54129c576..0000000000 --- a/testing/marionette/cert.js +++ /dev/null @@ -1,139 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Preferences.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -this.EXPORTED_SYMBOLS = ["cert"]; - -const registrar = - Components.manager.QueryInterface(Ci.nsIComponentRegistrar); -const sss = Cc["@mozilla.org/ssservice;1"] - .getService(Ci.nsISiteSecurityService); - -const CONTRACT_ID = "@mozilla.org/security/certoverride;1"; -const CERT_PINNING_ENFORCEMENT_PREF = - "security.cert_pinning.enforcement_level"; -const HSTS_PRELOAD_LIST_PREF = - "network.stricttransportsecurity.preloadlist"; - -/** TLS certificate service override management for Marionette. */ -this.cert = { - Error: { - Untrusted: 1, - Mismatch: 2, - Time: 4, - }, - - currentOverride: null, -}; - -/** - * Installs a TLS certificate service override. - * - * The provided |service| must implement the |register| and |unregister| - * functions that causes a new |nsICertOverrideService| interface - * implementation to be registered with the |nsIComponentRegistrar|. - * - * After |service| is registered and made the |cert.currentOverride|, - * |nsICertOverrideService| is reinitialised to cause all Gecko components - * to pick up the new service. - * - * If an override is already installed, i.e. when |cert.currentOverride| - * is not null, this functions acts as a NOOP. - * - * @param {cert.Override} service - * Service generator that registers and unregisters the XPCOM service. - * - * @throws {Components.Exception} - * If unable to register or initialise |service|. - */ -cert.installOverride = function (service) { - if (this.currentOverride) { - return; - } - - service.register(); - cert.currentOverride = service; -}; - -/** - * Uninstall a TLS certificate service override. - * - * After the service has been unregistered, |cert.currentOverride| - * is reset to null. - * - * If there no current override installed, i.e. if |cert.currentOverride| - * is null, this function acts as a NOOP. - */ -cert.uninstallOverride = function() { - if (!cert.currentOverride) { - return; - } - cert.currentOverride.unregister(); - this.currentOverride = null; -}; - -/** - * Certificate override service that acts in an all-inclusive manner - * on TLS certificates. - * - * When an invalid certificate is encountered, it is overriden - * with the |matching| bit level, which is typically a combination of - * |cert.Error.Untrusted|, |cert.Error.Mismatch|, and |cert.Error.Time|. - * - * @type cert.Override - * - * @throws {Components.Exception} - * If there are any problems registering the service. - */ -cert.InsecureSweepingOverride = function() { - const CID = Components.ID("{4b67cce0-a51c-11e6-9598-0800200c9a66}"); - const DESC = "All-encompassing cert service that matches on a bitflag"; - - // This needs to be an old-style class with a function constructor - // and prototype assignment because... XPCOM. Any attempt at - // modernisation will be met with cryptic error messages which will - // make your life miserable. - let service = function() {}; - service.prototype = { - hasMatchingOverride: function ( - aHostName, aPort, aCert, aOverrideBits, aIsTemporary) { - aIsTemporary.value = false; - aOverrideBits.value = - cert.Error.Untrusted | cert.Error.Mismatch | cert.Error.Time; - - return true; - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsICertOverrideService]), - }; - let factory = XPCOMUtils.generateSingletonFactory(service); - - return { - register: function() { - // make it possible to register certificate overrides for domains - // that use HSTS or HPKP - Preferences.set(HSTS_PRELOAD_LIST_PREF, false); - Preferences.set(CERT_PINNING_ENFORCEMENT_PREF, 0); - - registrar.registerFactory(CID, DESC, CONTRACT_ID, factory); - }, - - unregister: function() { - registrar.unregisterFactory(CID, factory); - - Preferences.reset(HSTS_PRELOAD_LIST_PREF); - Preferences.reset(CERT_PINNING_ENFORCEMENT_PREF); - - // clear collected HSTS and HPKP state - // through the site security service - sss.clearAll(); - }, - }; -}; diff --git a/testing/marionette/chrome/test.xul b/testing/marionette/chrome/test.xul deleted file mode 100644 index 2baa28e5ff..0000000000 --- a/testing/marionette/chrome/test.xul +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - -I'm a normal link -I go to an anchor -I open a window with javascript -Click me - -I'm a green link -

looooooooooong short looooooooooong -

- -
- click to add an event listener -
-
- this will show the button clicked -
-333333 -

I have a span

And another span

- - diff --git a/testing/marionette/harness/marionette_harness/www/cssTransform.html b/testing/marionette/harness/marionette_harness/www/cssTransform.html deleted file mode 100644 index c3b99648ac..0000000000 --- a/testing/marionette/harness/marionette_harness/www/cssTransform.html +++ /dev/null @@ -1,61 +0,0 @@ - - -
-You shouldn't see anything other than this sentence on the page -
-
- I have a hidden child -
- I am a hidden child -
-
-
- I have a hidden child -
- I am a hidden child -
-
-
I am a hidden element
-
I am a hidden element
diff --git a/testing/marionette/harness/marionette_harness/www/cssTransform2.html b/testing/marionette/harness/marionette_harness/www/cssTransform2.html deleted file mode 100644 index 602924bfbb..0000000000 --- a/testing/marionette/harness/marionette_harness/www/cssTransform2.html +++ /dev/null @@ -1,20 +0,0 @@ - - -
-
-
-
-
-
-
I am not a hidden element
diff --git a/testing/marionette/harness/marionette_harness/www/datetimePage.html b/testing/marionette/harness/marionette_harness/www/datetimePage.html deleted file mode 100644 index 87a05f6d26..0000000000 --- a/testing/marionette/harness/marionette_harness/www/datetimePage.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Testing date and time inputs - - -
- - -
- - diff --git a/testing/marionette/harness/marionette_harness/www/deletingFrame.html b/testing/marionette/harness/marionette_harness/www/deletingFrame.html deleted file mode 100644 index d891605aff..0000000000 --- a/testing/marionette/harness/marionette_harness/www/deletingFrame.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -
- - -
-
- -
- - - diff --git a/testing/marionette/harness/marionette_harness/www/double_click.html b/testing/marionette/harness/marionette_harness/www/double_click.html deleted file mode 100644 index fb3ec217a6..0000000000 --- a/testing/marionette/harness/marionette_harness/www/double_click.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Testing Double Click - -
-

zyxw

-
- -
-
- -
-
- diff --git a/testing/marionette/harness/marionette_harness/www/element_bottom.html b/testing/marionette/harness/marionette_harness/www/element_bottom.html deleted file mode 100644 index 470199a078..0000000000 --- a/testing/marionette/harness/marionette_harness/www/element_bottom.html +++ /dev/null @@ -1,12 +0,0 @@ - - -
- diff --git a/testing/marionette/harness/marionette_harness/www/element_left.html b/testing/marionette/harness/marionette_harness/www/element_left.html deleted file mode 100644 index c98b945f94..0000000000 --- a/testing/marionette/harness/marionette_harness/www/element_left.html +++ /dev/null @@ -1,12 +0,0 @@ - - -
- diff --git a/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html b/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html deleted file mode 100644 index 69b66b8759..0000000000 --- a/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html +++ /dev/null @@ -1,41 +0,0 @@ - - - -
-
-
-
-
-
-
-
-
-
-
-
- diff --git a/testing/marionette/harness/marionette_harness/www/element_right.html b/testing/marionette/harness/marionette_harness/www/element_right.html deleted file mode 100644 index ff8774ab6d..0000000000 --- a/testing/marionette/harness/marionette_harness/www/element_right.html +++ /dev/null @@ -1,12 +0,0 @@ - - -
- diff --git a/testing/marionette/harness/marionette_harness/www/element_top.html b/testing/marionette/harness/marionette_harness/www/element_top.html deleted file mode 100644 index b975e34c46..0000000000 --- a/testing/marionette/harness/marionette_harness/www/element_top.html +++ /dev/null @@ -1,12 +0,0 @@ - - -
- diff --git a/testing/marionette/harness/marionette_harness/www/empty.html b/testing/marionette/harness/marionette_harness/www/empty.html deleted file mode 100644 index 0a9d08cd62..0000000000 --- a/testing/marionette/harness/marionette_harness/www/empty.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - -Marionette Test - - - - diff --git a/testing/marionette/harness/marionette_harness/www/formPage.html b/testing/marionette/harness/marionette_harness/www/formPage.html deleted file mode 100644 index ee1ff9f2b9..0000000000 --- a/testing/marionette/harness/marionette_harness/www/formPage.html +++ /dev/null @@ -1,116 +0,0 @@ - - - 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 deleted file mode 100644 index 209d705b5a..0000000000 --- a/testing/marionette/harness/marionette_harness/www/frameset.html +++ /dev/null @@ -1,14 +0,0 @@ - - - Unique title - - - - - - - - - - - \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/framesetPage2.html b/testing/marionette/harness/marionette_harness/www/framesetPage2.html deleted file mode 100644 index 5190ceb6ce..0000000000 --- a/testing/marionette/harness/marionette_harness/www/framesetPage2.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/hidden.html b/testing/marionette/harness/marionette_harness/www/hidden.html deleted file mode 100644 index 0e8097e973..0000000000 --- a/testing/marionette/harness/marionette_harness/www/hidden.html +++ /dev/null @@ -1,5 +0,0 @@ - - - \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/html5/blue.jpg b/testing/marionette/harness/marionette_harness/www/html5/blue.jpg deleted file mode 100644 index 8ea27c42fa..0000000000 Binary files a/testing/marionette/harness/marionette_harness/www/html5/blue.jpg and /dev/null 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 deleted file mode 100644 index eb0d458b84..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/html5/geolocation.js b/testing/marionette/harness/marionette_harness/www/html5/geolocation.js deleted file mode 100644 index f07af148ed..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/geolocation.js +++ /dev/null @@ -1,18 +0,0 @@ -function success(position) { - var 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) { - var message = document.getElementById("status"); - message.innerHTML = "Failed to get geolocation."; -} - -if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(success, error); -} else { - error('Geolocation is not supported.'); -} \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/html5/green.jpg b/testing/marionette/harness/marionette_harness/www/html5/green.jpg deleted file mode 100644 index 6a0d3bea47..0000000000 Binary files a/testing/marionette/harness/marionette_harness/www/html5/green.jpg and /dev/null differ diff --git a/testing/marionette/harness/marionette_harness/www/html5/offline.html b/testing/marionette/harness/marionette_harness/www/html5/offline.html deleted file mode 100644 index c24178b5f5..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/offline.html +++ /dev/null @@ -1 +0,0 @@ -Offline diff --git a/testing/marionette/harness/marionette_harness/www/html5/red.jpg b/testing/marionette/harness/marionette_harness/www/html5/red.jpg deleted file mode 100644 index f296e27195..0000000000 Binary files a/testing/marionette/harness/marionette_harness/www/html5/red.jpg and /dev/null differ diff --git a/testing/marionette/harness/marionette_harness/www/html5/status.html b/testing/marionette/harness/marionette_harness/www/html5/status.html deleted file mode 100644 index 394116a522..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/status.html +++ /dev/null @@ -1 +0,0 @@ -Online diff --git a/testing/marionette/harness/marionette_harness/www/html5/test.appcache b/testing/marionette/harness/marionette_harness/www/html5/test.appcache deleted file mode 100644 index 3bc4e00257..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/test.appcache +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 96c9b97e3b..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg b/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg deleted file mode 100644 index 7c609b3712..0000000000 Binary files a/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg and /dev/null differ diff --git a/testing/marionette/harness/marionette_harness/www/html5Page.html b/testing/marionette/harness/marionette_harness/www/html5Page.html deleted file mode 100644 index 4197cd1226..0000000000 --- a/testing/marionette/harness/marionette_harness/www/html5Page.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - -HTML5 - - - -

Geolocation Test

-
Location unknown
- - -

Application Cache Test

-
-

Current network status:

- - - - - -
- - - diff --git a/testing/marionette/harness/marionette_harness/www/javascriptPage.html b/testing/marionette/harness/marionette_harness/www/javascriptPage.html deleted file mode 100644 index b47c902c5e..0000000000 --- a/testing/marionette/harness/marionette_harness/www/javascriptPage.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - Testing Javascript - - - - - -

Type Stuff

- -
- -
- -
  -
-

 

-
- -
- -
-
- Key Up:
- Key Down:
- Key Press:
- Change:
- - - - - - - - -
-
- - - -
What's for dinner?
- -
-

Click for the mouse down event

-

Here's some text

-
- -
-

Click for the mouse up event

-
- -
-

Click for the mouse click event

-
- -
-

Click to show button

-
- -
- Clicking this causes a JS exception in the click handler -
- -
-
- - - - - - - - - -
- -
- -
-

- - -

-
-
- - - -
-

Displayed

- -
- - - - - - - -
- - - Check box you can't see - -
- - -
- -
-
- - -
-
- - -
-

This should be greenish

-
    -
  • So should this
  • -
  • But this is red
  • -
-
- -Close window - -
-

I should be deleted when you click my containing div

-

Whereas, I should not

-
- -
- Click to hide me. -
- -
- Click actions delayed by 3000ms: -
- Click to show black box -
- -
-
- -Click me to open a new window - -Mouse over me will throw a JS error - -
- - Click on me to show the related target - -
- -
-
- -
-
- - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/macbeth.html b/testing/marionette/harness/marionette_harness/www/macbeth.html deleted file mode 100644 index 2404f1d727..0000000000 --- a/testing/marionette/harness/marionette_harness/www/macbeth.html +++ /dev/null @@ -1,5254 +0,0 @@ - - - - Macbeth: Entire Play - - - - - - - -Quick link to last speech - -

ACT I

-

SCENE I. A desert place.

-

-Thunder and lightning. Enter three Witches -
- -First Witch -
-When shall we three meet again
-In thunder, lightning, or in rain?
-
- -Second Witch -
-When the hurlyburly's done,
-When the battle's lost and won.
-
- -Third Witch -
-That will be ere the set of sun.
-
- -First Witch -
-Where the place?
-
- -Second Witch -
- Upon the heath.
-
- -Third Witch -
-There to meet with Macbeth.
-
- -First Witch -
-I come, Graymalkin!
-
- -Second Witch -
-Paddock calls.
-
- -Third Witch -
-Anon.
-
- -ALL -
-Fair is foul, and foul is fair:
-Hover through the fog and filthy air.
-

Exeunt

-
-

SCENE II. A camp near Forres.

-

-Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant -
- -DUNCAN -
-What bloody man is that? He can report,
-As seemeth by his plight, of the revolt
-The newest state.
-
- -MALCOLM -
- This is the sergeant
-Who like a good and hardy soldier fought
-'Gainst my captivity. Hail, brave friend!
-Say to the king the knowledge of the broil
-As thou didst leave it.
-
- -Sergeant -
-Doubtful it stood;
-As two spent swimmers, that do cling together
-And choke their art. The merciless Macdonwald--
-Worthy to be a rebel, for to that
-The multiplying villanies of nature
-Do swarm upon him--from the western isles
-Of kerns and gallowglasses is supplied;
-And fortune, on his damned quarrel smiling,
-Show'd like a rebel's whore: but all's too weak:
-For brave Macbeth--well he deserves that name--
-Disdaining fortune, with his brandish'd steel,
-Which smoked with bloody execution,
-Like valour's minion carved out his passage
-Till he faced the slave;
-Which ne'er shook hands, nor bade farewell to him,
-Till he unseam'd him from the nave to the chaps,
-And fix'd his head upon our battlements.
-
- -DUNCAN -
-O valiant cousin! worthy gentleman!
-
- -Sergeant -
-As whence the sun 'gins his reflection
-Shipwrecking storms and direful thunders break,
-So from that spring whence comfort seem'd to come
-Discomfort swells. Mark, king of Scotland, mark:
-No sooner justice had with valour arm'd
-Compell'd these skipping kerns to trust their heels,
-But the Norweyan lord surveying vantage,
-With furbish'd arms and new supplies of men
-Began a fresh assault.
-
- -DUNCAN -
-Dismay'd not this
-Our captains, Macbeth and Banquo?
-
- -Sergeant -
-Yes;
-As sparrows eagles, or the hare the lion.
-If I say sooth, I must report they were
-As cannons overcharged with double cracks, so they
-Doubly redoubled strokes upon the foe:
-Except they meant to bathe in reeking wounds,
-Or memorise another Golgotha,
-I cannot tell.
-But I am faint, my gashes cry for help.
-
- -DUNCAN -
-So well thy words become thee as thy wounds;
-They smack of honour both. Go get him surgeons.
-

Exit Sergeant, attended

-Who comes here?
-

Enter ROSS

-
- -MALCOLM -
- The worthy thane of Ross.
-
- -LENNOX -
-What a haste looks through his eyes! So should he look
-That seems to speak things strange.
-
- -ROSS -
-God save the king!
-
- -DUNCAN -
-Whence camest thou, worthy thane?
-
- -ROSS -
-From Fife, great king;
-Where the Norweyan banners flout the sky
-And fan our people cold. Norway himself,
-With terrible numbers,
-Assisted by that most disloyal traitor
-The thane of Cawdor, began a dismal conflict;
-Till that Bellona's bridegroom, lapp'd in proof,
-Confronted him with self-comparisons,
-Point against point rebellious, arm 'gainst arm.
-Curbing his lavish spirit: and, to conclude,
-The victory fell on us.
-
- -DUNCAN -
-Great happiness!
-
- -ROSS -
-That now
-Sweno, the Norways' king, craves composition:
-Nor would we deign him burial of his men
-Till he disbursed at Saint Colme's inch
-Ten thousand dollars to our general use.
-
- -DUNCAN -
-No more that thane of Cawdor shall deceive
-Our bosom interest: go pronounce his present death,
-And with his former title greet Macbeth.
-
- -ROSS -
-I'll see it done.
-
- -DUNCAN -
-What he hath lost noble Macbeth hath won.
-

Exeunt

-
-

SCENE III. A heath near Forres.

-

-Thunder. Enter the three Witches -
- -First Witch -
-Where hast thou been, sister?
-
- -Second Witch -
-Killing swine.
-
- -Third Witch -
-Sister, where thou?
-
- -First Witch -
-A sailor's wife had chestnuts in her lap,
-And munch'd, and munch'd, and munch'd:--
-'Give me,' quoth I:
-'Aroint thee, witch!' the rump-fed ronyon cries.
-Her husband's to Aleppo gone, master o' the Tiger:
-But in a sieve I'll thither sail,
-And, like a rat without a tail,
-I'll do, I'll do, and I'll do.
-
- -Second Witch -
-I'll give thee a wind.
-
- -First Witch -
-Thou'rt kind.
-
- -Third Witch -
-And I another.
-
- -First Witch -
-I myself have all the other,
-And the very ports they blow,
-All the quarters that they know
-I' the shipman's card.
-I will drain him dry as hay:
-Sleep shall neither night nor day
-Hang upon his pent-house lid;
-He shall live a man forbid:
-Weary se'nnights nine times nine
-Shall he dwindle, peak and pine:
-Though his bark cannot be lost,
-Yet it shall be tempest-tost.
-Look what I have.
-
- -Second Witch -
-Show me, show me.
-
- -First Witch -
-Here I have a pilot's thumb,
-Wreck'd as homeward he did come.
-

Drum within

-
- -Third Witch -
-A drum, a drum!
-Macbeth doth come.
-
- -ALL -
-The weird sisters, hand in hand,
-Posters of the sea and land,
-Thus do go about, about:
-Thrice to thine and thrice to mine
-And thrice again, to make up nine.
-Peace! the charm's wound up.
-

Enter MACBETH and BANQUO

-
- -MACBETH -
-So foul and fair a day I have not seen.
-
- -BANQUO -
-How far is't call'd to Forres? What are these
-So wither'd and so wild in their attire,
-That look not like the inhabitants o' the earth,
-And yet are on't? Live you? or are you aught
-That man may question? You seem to understand me,
-By each at once her chappy finger laying
-Upon her skinny lips: you should be women,
-And yet your beards forbid me to interpret
-That you are so.
-
- -MACBETH -
- Speak, if you can: what are you?
-
- -First Witch -
-All hail, Macbeth! hail to thee, thane of Glamis!
-
- -Second Witch -
-All hail, Macbeth, hail to thee, thane of Cawdor!
-
- -Third Witch -
-All hail, Macbeth, thou shalt be king hereafter!
-
- -BANQUO -
-Good sir, why do you start; and seem to fear
-Things that do sound so fair? I' the name of truth,
-Are ye fantastical, or that indeed
-Which outwardly ye show? My noble partner
-You greet with present grace and great prediction
-Of noble having and of royal hope,
-That he seems rapt withal: to me you speak not.
-If you can look into the seeds of time,
-And say which grain will grow and which will not,
-Speak then to me, who neither beg nor fear
-Your favours nor your hate.
-
- -First Witch -
-Hail!
-
- -Second Witch -
-Hail!
-
- -Third Witch -
-Hail!
-
- -First Witch -
-Lesser than Macbeth, and greater.
-
- -Second Witch -
-Not so happy, yet much happier.
-
- -Third Witch -
-Thou shalt get kings, though thou be none:
-So all hail, Macbeth and Banquo!
-
- -First Witch -
-Banquo and Macbeth, all hail!
-
- -MACBETH -
-Stay, you imperfect speakers, tell me more:
-By Sinel's death I know I am thane of Glamis;
-But how of Cawdor? the thane of Cawdor lives,
-A prosperous gentleman; and to be king
-Stands not within the prospect of belief,
-No more than to be Cawdor. Say from whence
-You owe this strange intelligence? or why
-Upon this blasted heath you stop our way
-With such prophetic greeting? Speak, I charge you.
-

Witches vanish

-
- -BANQUO -
-The earth hath bubbles, as the water has,
-And these are of them. Whither are they vanish'd?
-
- -MACBETH -
-Into the air; and what seem'd corporal melted
-As breath into the wind. Would they had stay'd!
-
- -BANQUO -
-Were such things here as we do speak about?
-Or have we eaten on the insane root
-That takes the reason prisoner?
-
- -MACBETH -
-Your children shall be kings.
-
- -BANQUO -
-You shall be king.
-
- -MACBETH -
-And thane of Cawdor too: went it not so?
-
- -BANQUO -
-To the selfsame tune and words. Who's here?
-

Enter ROSS and ANGUS

-
- -ROSS -
-The king hath happily received, Macbeth,
-The news of thy success; and when he reads
-Thy personal venture in the rebels' fight,
-His wonders and his praises do contend
-Which should be thine or his: silenced with that,
-In viewing o'er the rest o' the selfsame day,
-He finds thee in the stout Norweyan ranks,
-Nothing afeard of what thyself didst make,
-Strange images of death. As thick as hail
-Came post with post; and every one did bear
-Thy praises in his kingdom's great defence,
-And pour'd them down before him.
-
- -ANGUS -
-We are sent
-To give thee from our royal master thanks;
-Only to herald thee into his sight,
-Not pay thee.
-
- -ROSS -
-And, for an earnest of a greater honour,
-He bade me, from him, call thee thane of Cawdor:
-In which addition, hail, most worthy thane!
-For it is thine.
-
- -BANQUO -
- What, can the devil speak true?
-
- -MACBETH -
-The thane of Cawdor lives: why do you dress me
-In borrow'd robes?
-
- -ANGUS -
- Who was the thane lives yet;
-But under heavy judgment bears that life
-Which he deserves to lose. Whether he was combined
-With those of Norway, or did line the rebel
-With hidden help and vantage, or that with both
-He labour'd in his country's wreck, I know not;
-But treasons capital, confess'd and proved,
-Have overthrown him.
-
- -MACBETH -
-[Aside] Glamis, and thane of Cawdor!
-The greatest is behind.
-

To ROSS and ANGUS

-Thanks for your pains.
-

To BANQUO

-Do you not hope your children shall be kings,
-When those that gave the thane of Cawdor to me
-Promised no less to them?
-
- -BANQUO -
-That trusted home
-Might yet enkindle you unto the crown,
-Besides the thane of Cawdor. But 'tis strange:
-And oftentimes, to win us to our harm,
-The instruments of darkness tell us truths,
-Win us with honest trifles, to betray's
-In deepest consequence.
-Cousins, a word, I pray you.
-
- -MACBETH -
-[Aside] Two truths are told,
-As happy prologues to the swelling act
-Of the imperial theme.--I thank you, gentlemen.
-

Aside

-Cannot be ill, cannot be good: if ill,
-Why hath it given me earnest of success,
-Commencing in a truth? I am thane of Cawdor:
-If good, why do I yield to that suggestion
-Whose horrid image doth unfix my hair
-And make my seated heart knock at my ribs,
-Against the use of nature? Present fears
-Are less than horrible imaginings:
-My thought, whose murder yet is but fantastical,
-Shakes so my single state of man that function
-Is smother'd in surmise, and nothing is
-But what is not.
-
- -BANQUO -
- Look, how our partner's rapt.
-
- -MACBETH -
-[Aside] If chance will have me king, why, chance may crown me,
-Without my stir.
-
- -BANQUO -
- New horrors come upon him,
-Like our strange garments, cleave not to their mould
-But with the aid of use.
-
- -MACBETH -
-[Aside] Come what come may,
-Time and the hour runs through the roughest day.
-
- -BANQUO -
-Worthy Macbeth, we stay upon your leisure.
-
- -MACBETH -
-Give me your favour: my dull brain was wrought
-With things forgotten. Kind gentlemen, your pains
-Are register'd where every day I turn
-The leaf to read them. Let us toward the king.
-Think upon what hath chanced, and, at more time,
-The interim having weigh'd it, let us speak
-Our free hearts each to other.
-
- -BANQUO -
-Very gladly.
-
- -MACBETH -
-Till then, enough. Come, friends.
-

Exeunt

-
-

SCENE IV. Forres. The palace.

-

-Flourish. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, and Attendants -
- -DUNCAN -
-Is execution done on Cawdor? Are not
-Those in commission yet return'd?
-
- -MALCOLM -
-My liege,
-They are not yet come back. But I have spoke
-With one that saw him die: who did report
-That very frankly he confess'd his treasons,
-Implored your highness' pardon and set forth
-A deep repentance: nothing in his life
-Became him like the leaving it; he died
-As one that had been studied in his death
-To throw away the dearest thing he owed,
-As 'twere a careless trifle.
-
- -DUNCAN -
-There's no art
-To find the mind's construction in the face:
-He was a gentleman on whom I built
-An absolute trust.
-

Enter MACBETH, BANQUO, ROSS, and ANGUS

-O worthiest cousin!
-The sin of my ingratitude even now
-Was heavy on me: thou art so far before
-That swiftest wing of recompense is slow
-To overtake thee. Would thou hadst less deserved,
-That the proportion both of thanks and payment
-Might have been mine! only I have left to say,
-More is thy due than more than all can pay.
-
- -MACBETH -
-The service and the loyalty I owe,
-In doing it, pays itself. Your highness' part
-Is to receive our duties; and our duties
-Are to your throne and state children and servants,
-Which do but what they should, by doing every thing
-Safe toward your love and honour.
-
- -DUNCAN -
-Welcome hither:
-I have begun to plant thee, and will labour
-To make thee full of growing. Noble Banquo,
-That hast no less deserved, nor must be known
-No less to have done so, let me enfold thee
-And hold thee to my heart.
-
- -BANQUO -
-There if I grow,
-The harvest is your own.
-
- -DUNCAN -
-My plenteous joys,
-Wanton in fulness, seek to hide themselves
-In drops of sorrow. Sons, kinsmen, thanes,
-And you whose places are the nearest, know
-We will establish our estate upon
-Our eldest, Malcolm, whom we name hereafter
-The Prince of Cumberland; which honour must
-Not unaccompanied invest him only,
-But signs of nobleness, like stars, shall shine
-On all deservers. From hence to Inverness,
-And bind us further to you.
-
- -MACBETH -
-The rest is labour, which is not used for you:
-I'll be myself the harbinger and make joyful
-The hearing of my wife with your approach;
-So humbly take my leave.
-
- -DUNCAN -
-My worthy Cawdor!
-
- -MACBETH -
-[Aside] The Prince of Cumberland! that is a step
-On which I must fall down, or else o'erleap,
-For in my way it lies. Stars, hide your fires;
-Let not light see my black and deep desires:
-The eye wink at the hand; yet let that be,
-Which the eye fears, when it is done, to see.
-

Exit

-
- -DUNCAN -
-True, worthy Banquo; he is full so valiant,
-And in his commendations I am fed;
-It is a banquet to me. Let's after him,
-Whose care is gone before to bid us welcome:
-It is a peerless kinsman.
-

Flourish. Exeunt

-
-

SCENE V. Inverness. Macbeth's castle.

-

-Enter LADY MACBETH, reading a letter -
- -LADY MACBETH -
-'They met me in the day of success: and I have
-learned by the perfectest report, they have more in
-them than mortal knowledge. When I burned in desire
-to question them further, they made themselves air,
-into which they vanished. Whiles I stood rapt in
-the wonder of it, came missives from the king, who
-all-hailed me 'Thane of Cawdor;' by which title,
-before, these weird sisters saluted me, and referred
-me to the coming on of time, with 'Hail, king that
-shalt be!' This have I thought good to deliver
-thee, my dearest partner of greatness, that thou
-mightst not lose the dues of rejoicing, by being
-ignorant of what greatness is promised thee. Lay it
-to thy heart, and farewell.'
-Glamis thou art, and Cawdor; and shalt be
-What thou art promised: yet do I fear thy nature;
-It is too full o' the milk of human kindness
-To catch the nearest way: thou wouldst be great;
-Art not without ambition, but without
-The illness should attend it: what thou wouldst highly,
-That wouldst thou holily; wouldst not play false,
-And yet wouldst wrongly win: thou'ldst have, great Glamis,
-That which cries 'Thus thou must do, if thou have it;
-And that which rather thou dost fear to do
-Than wishest should be undone.' Hie thee hither,
-That I may pour my spirits in thine ear;
-And chastise with the valour of my tongue
-All that impedes thee from the golden round,
-Which fate and metaphysical aid doth seem
-To have thee crown'd withal.
-

Enter a Messenger

-What is your tidings?
-
- -Messenger -
-The king comes here to-night.
-
- -LADY MACBETH -
-Thou'rt mad to say it:
-Is not thy master with him? who, were't so,
-Would have inform'd for preparation.
-
- -Messenger -
-So please you, it is true: our thane is coming:
-One of my fellows had the speed of him,
-Who, almost dead for breath, had scarcely more
-Than would make up his message.
-
- -LADY MACBETH -
-Give him tending;
-He brings great news.
-

Exit Messenger

-The raven himself is hoarse
-That croaks the fatal entrance of Duncan
-Under my battlements. Come, you spirits
-That tend on mortal thoughts, unsex me here,
-And fill me from the crown to the toe top-full
-Of direst cruelty! make thick my blood;
-Stop up the access and passage to remorse,
-That no compunctious visitings of nature
-Shake my fell purpose, nor keep peace between
-The effect and it! Come to my woman's breasts,
-And take my milk for gall, you murdering ministers,
-Wherever in your sightless substances
-You wait on nature's mischief! Come, thick night,
-And pall thee in the dunnest smoke of hell,
-That my keen knife see not the wound it makes,
-Nor heaven peep through the blanket of the dark,
-To cry 'Hold, hold!'
-

Enter MACBETH

-Great Glamis! worthy Cawdor!
-Greater than both, by the all-hail hereafter!
-Thy letters have transported me beyond
-This ignorant present, and I feel now
-The future in the instant.
-
- -MACBETH -
-My dearest love,
-Duncan comes here to-night.
-
- -LADY MACBETH -
-And when goes hence?
-
- -MACBETH -
-To-morrow, as he purposes.
-
- -LADY MACBETH -
-O, never
-Shall sun that morrow see!
-Your face, my thane, is as a book where men
-May read strange matters. To beguile the time,
-Look like the time; bear welcome in your eye,
-Your hand, your tongue: look like the innocent flower,
-But be the serpent under't. He that's coming
-Must be provided for: and you shall put
-This night's great business into my dispatch;
-Which shall to all our nights and days to come
-Give solely sovereign sway and masterdom.
-
- -MACBETH -
-We will speak further.
-
- -LADY MACBETH -
-Only look up clear;
-To alter favour ever is to fear:
-Leave all the rest to me.
-

Exeunt

-
-

SCENE VI. Before Macbeth's castle.

-

-Hautboys and torches. Enter DUNCAN, MALCOLM, DONALBAIN, BANQUO, LENNOX, MACDUFF, ROSS, ANGUS, and Attendants -
- -DUNCAN -
-This castle hath a pleasant seat; the air
-Nimbly and sweetly recommends itself
-Unto our gentle senses.
-
- -BANQUO -
-This guest of summer,
-The temple-haunting martlet, does approve,
-By his loved mansionry, that the heaven's breath
-Smells wooingly here: no jutty, frieze,
-Buttress, nor coign of vantage, but this bird
-Hath made his pendent bed and procreant cradle:
-Where they most breed and haunt, I have observed,
-The air is delicate.
-

Enter LADY MACBETH

-
- -DUNCAN -
-See, see, our honour'd hostess!
-The love that follows us sometime is our trouble,
-Which still we thank as love. Herein I teach you
-How you shall bid God 'ild us for your pains,
-And thank us for your trouble.
-
- -LADY MACBETH -
-All our service
-In every point twice done and then done double
-Were poor and single business to contend
-Against those honours deep and broad wherewith
-Your majesty loads our house: for those of old,
-And the late dignities heap'd up to them,
-We rest your hermits.
-
- -DUNCAN -
-Where's the thane of Cawdor?
-We coursed him at the heels, and had a purpose
-To be his purveyor: but he rides well;
-And his great love, sharp as his spur, hath holp him
-To his home before us. Fair and noble hostess,
-We are your guest to-night.
-
- -LADY MACBETH -
-Your servants ever
-Have theirs, themselves and what is theirs, in compt,
-To make their audit at your highness' pleasure,
-Still to return your own.
-
- -DUNCAN -
-Give me your hand;
-Conduct me to mine host: we love him highly,
-And shall continue our graces towards him.
-By your leave, hostess.
-

Exeunt

-
-

SCENE VII. Macbeth's castle.

-

-Hautboys and torches. Enter a Sewer, and divers Servants with dishes and service, and pass over the stage. Then enter MACBETH -
- -MACBETH -
-If it were done when 'tis done, then 'twere well
-It were done quickly: if the assassination
-Could trammel up the consequence, and catch
-With his surcease success; that but this blow
-Might be the be-all and the end-all here,
-But here, upon this bank and shoal of time,
-We'ld jump the life to come. But in these cases
-We still have judgment here; that we but teach
-Bloody instructions, which, being taught, return
-To plague the inventor: this even-handed justice
-Commends the ingredients of our poison'd chalice
-To our own lips. He's here in double trust;
-First, as I am his kinsman and his subject,
-Strong both against the deed; then, as his host,
-Who should against his murderer shut the door,
-Not bear the knife myself. Besides, this Duncan
-Hath borne his faculties so meek, hath been
-So clear in his great office, that his virtues
-Will plead like angels, trumpet-tongued, against
-The deep damnation of his taking-off;
-And pity, like a naked new-born babe,
-Striding the blast, or heaven's cherubim, horsed
-Upon the sightless couriers of the air,
-Shall blow the horrid deed in every eye,
-That tears shall drown the wind. I have no spur
-To prick the sides of my intent, but only
-Vaulting ambition, which o'erleaps itself
-And falls on the other.
-

Enter LADY MACBETH

-How now! what news?
-
- -LADY MACBETH -
-He has almost supp'd: why have you left the chamber?
-
- -MACBETH -
-Hath he ask'd for me?
-
- -LADY MACBETH -
-Know you not he has?
-
- -MACBETH -
-We will proceed no further in this business:
-He hath honour'd me of late; and I have bought
-Golden opinions from all sorts of people,
-Which would be worn now in their newest gloss,
-Not cast aside so soon.
-
- -LADY MACBETH -
-Was the hope drunk
-Wherein you dress'd yourself? hath it slept since?
-And wakes it now, to look so green and pale
-At what it did so freely? From this time
-Such I account thy love. Art thou afeard
-To be the same in thine own act and valour
-As thou art in desire? Wouldst thou have that
-Which thou esteem'st the ornament of life,
-And live a coward in thine own esteem,
-Letting 'I dare not' wait upon 'I would,'
-Like the poor cat i' the adage?
-
- -MACBETH -
-Prithee, peace:
-I dare do all that may become a man;
-Who dares do more is none.
-
- -LADY MACBETH -
-What beast was't, then,
-That made you break this enterprise to me?
-When you durst do it, then you were a man;
-And, to be more than what you were, you would
-Be so much more the man. Nor time nor place
-Did then adhere, and yet you would make both:
-They have made themselves, and that their fitness now
-Does unmake you. I have given suck, and know
-How tender 'tis to love the babe that milks me:
-I would, while it was smiling in my face,
-Have pluck'd my nipple from his boneless gums,
-And dash'd the brains out, had I so sworn as you
-Have done to this.
-
- -MACBETH -
- If we should fail?
-
- -LADY MACBETH -
-We fail!
-But screw your courage to the sticking-place,
-And we'll not fail. When Duncan is asleep--
-Whereto the rather shall his day's hard journey
-Soundly invite him--his two chamberlains
-Will I with wine and wassail so convince
-That memory, the warder of the brain,
-Shall be a fume, and the receipt of reason
-A limbeck only: when in swinish sleep
-Their drenched natures lie as in a death,
-What cannot you and I perform upon
-The unguarded Duncan? what not put upon
-His spongy officers, who shall bear the guilt
-Of our great quell?
-
- -MACBETH -
-Bring forth men-children only;
-For thy undaunted mettle should compose
-Nothing but males. Will it not be received,
-When we have mark'd with blood those sleepy two
-Of his own chamber and used their very daggers,
-That they have done't?
-
- -LADY MACBETH -
-Who dares receive it other,
-As we shall make our griefs and clamour roar
-Upon his death?
-
- -MACBETH -
- I am settled, and bend up
-Each corporal agent to this terrible feat.
-Away, and mock the time with fairest show:
-False face must hide what the false heart doth know.
-

Exeunt

-

-

ACT II

-

SCENE I. Court of Macbeth's castle.

-

-Enter BANQUO, and FLEANCE bearing a torch before him -
- -BANQUO -
-How goes the night, boy?
-
- -FLEANCE -
-The moon is down; I have not heard the clock.
-
- -BANQUO -
-And she goes down at twelve.
-
- -FLEANCE -
-I take't, 'tis later, sir.
-
- -BANQUO -
-Hold, take my sword. There's husbandry in heaven;
-Their candles are all out. Take thee that too.
-A heavy summons lies like lead upon me,
-And yet I would not sleep: merciful powers,
-Restrain in me the cursed thoughts that nature
-Gives way to in repose!
-

Enter MACBETH, and a Servant with a torch

-Give me my sword.
-Who's there?
-
- -MACBETH -
-A friend.
-
- -BANQUO -
-What, sir, not yet at rest? The king's a-bed:
-He hath been in unusual pleasure, and
-Sent forth great largess to your offices.
-This diamond he greets your wife withal,
-By the name of most kind hostess; and shut up
-In measureless content.
-
- -MACBETH -
-Being unprepared,
-Our will became the servant to defect;
-Which else should free have wrought.
-
- -BANQUO -
-All's well.
-I dreamt last night of the three weird sisters:
-To you they have show'd some truth.
-
- -MACBETH -
-I think not of them:
-Yet, when we can entreat an hour to serve,
-We would spend it in some words upon that business,
-If you would grant the time.
-
- -BANQUO -
-At your kind'st leisure.
-
- -MACBETH -
-If you shall cleave to my consent, when 'tis,
-It shall make honour for you.
-
- -BANQUO -
-So I lose none
-In seeking to augment it, but still keep
-My bosom franchised and allegiance clear,
-I shall be counsell'd.
-
- -MACBETH -
-Good repose the while!
-
- -BANQUO -
-Thanks, sir: the like to you!
-

Exeunt BANQUO and FLEANCE

-
- -MACBETH -
-Go bid thy mistress, when my drink is ready,
-She strike upon the bell. Get thee to bed.
-

Exit Servant

-Is this a dagger which I see before me,
-The handle toward my hand? Come, let me clutch thee.
-I have thee not, and yet I see thee still.
-Art thou not, fatal vision, sensible
-To feeling as to sight? or art thou but
-A dagger of the mind, a false creation,
-Proceeding from the heat-oppressed brain?
-I see thee yet, in form as palpable
-As this which now I draw.
-Thou marshall'st me the way that I was going;
-And such an instrument I was to use.
-Mine eyes are made the fools o' the other senses,
-Or else worth all the rest; I see thee still,
-And on thy blade and dudgeon gouts of blood,
-Which was not so before. There's no such thing:
-It is the bloody business which informs
-Thus to mine eyes. Now o'er the one halfworld
-Nature seems dead, and wicked dreams abuse
-The curtain'd sleep; witchcraft celebrates
-Pale Hecate's offerings, and wither'd murder,
-Alarum'd by his sentinel, the wolf,
-Whose howl's his watch, thus with his stealthy pace.
-With Tarquin's ravishing strides, towards his design
-Moves like a ghost. Thou sure and firm-set earth,
-Hear not my steps, which way they walk, for fear
-Thy very stones prate of my whereabout,
-And take the present horror from the time,
-Which now suits with it. Whiles I threat, he lives:
-Words to the heat of deeds too cold breath gives.
-

A bell rings

-I go, and it is done; the bell invites me.
-Hear it not, Duncan; for it is a knell
-That summons thee to heaven or to hell.
-

Exit

-
-

SCENE II. The same.

-

-Enter LADY MACBETH -
- -LADY MACBETH -
-That which hath made them drunk hath made me bold;
-What hath quench'd them hath given me fire.
-Hark! Peace!
-It was the owl that shriek'd, the fatal bellman,
-Which gives the stern'st good-night. He is about it:
-The doors are open; and the surfeited grooms
-Do mock their charge with snores: I have drugg'd
-their possets,
-That death and nature do contend about them,
-Whether they live or die.
-
- -MACBETH -
-[Within] Who's there? what, ho!
-
- -LADY MACBETH -
-Alack, I am afraid they have awaked,
-And 'tis not done. The attempt and not the deed
-Confounds us. Hark! I laid their daggers ready;
-He could not miss 'em. Had he not resembled
-My father as he slept, I had done't.
-

Enter MACBETH

-My husband!
-
- -MACBETH -
-I have done the deed. Didst thou not hear a noise?
-
- -LADY MACBETH -
-I heard the owl scream and the crickets cry.
-Did not you speak?
-
- -MACBETH -
- When?
-
- -LADY MACBETH -
-Now.
-
- -MACBETH -
-As I descended?
-
- -LADY MACBETH -
-Ay.
-
- -MACBETH -
-Hark!
-Who lies i' the second chamber?
-
- -LADY MACBETH -
-Donalbain.
-
- -MACBETH -
-This is a sorry sight.
-

Looking on his hands

-
- -LADY MACBETH -
-A foolish thought, to say a sorry sight.
-
- -MACBETH -
-There's one did laugh in's sleep, and one cried
-'Murder!'
-That they did wake each other: I stood and heard them:
-But they did say their prayers, and address'd them
-Again to sleep.
-
- -LADY MACBETH -
- There are two lodged together.
-
- -MACBETH -
-One cried 'God bless us!' and 'Amen' the other;
-As they had seen me with these hangman's hands.
-Listening their fear, I could not say 'Amen,'
-When they did say 'God bless us!'
-
- -LADY MACBETH -
-Consider it not so deeply.
-
- -MACBETH -
-But wherefore could not I pronounce 'Amen'?
-I had most need of blessing, and 'Amen'
-Stuck in my throat.
-
- -LADY MACBETH -
-These deeds must not be thought
-After these ways; so, it will make us mad.
-
- -MACBETH -
-Methought I heard a voice cry 'Sleep no more!
-Macbeth does murder sleep', the innocent sleep,
-Sleep that knits up the ravell'd sleeve of care,
-The death of each day's life, sore labour's bath,
-Balm of hurt minds, great nature's second course,
-Chief nourisher in life's feast,--
-
- -LADY MACBETH -
-What do you mean?
-
- -MACBETH -
-Still it cried 'Sleep no more!' to all the house:
-'Glamis hath murder'd sleep, and therefore Cawdor
-Shall sleep no more; Macbeth shall sleep no more.'
-
- -LADY MACBETH -
-Who was it that thus cried? Why, worthy thane,
-You do unbend your noble strength, to think
-So brainsickly of things. Go get some water,
-And wash this filthy witness from your hand.
-Why did you bring these daggers from the place?
-They must lie there: go carry them; and smear
-The sleepy grooms with blood.
-
- -MACBETH -
-I'll go no more:
-I am afraid to think what I have done;
-Look on't again I dare not.
-
- -LADY MACBETH -
-Infirm of purpose!
-Give me the daggers: the sleeping and the dead
-Are but as pictures: 'tis the eye of childhood
-That fears a painted devil. If he do bleed,
-I'll gild the faces of the grooms withal;
-For it must seem their guilt.
-

Exit. Knocking within

-
- -MACBETH -
-Whence is that knocking?
-How is't with me, when every noise appals me?
-What hands are here? ha! they pluck out mine eyes.
-Will all great Neptune's ocean wash this blood
-Clean from my hand? No, this my hand will rather
-The multitudinous seas in incarnadine,
-Making the green one red.
-

Re-enter LADY MACBETH

-
- -LADY MACBETH -
-My hands are of your colour; but I shame
-To wear a heart so white.
-

Knocking within

-I hear a knocking
-At the south entry: retire we to our chamber;
-A little water clears us of this deed:
-How easy is it, then! Your constancy
-Hath left you unattended.
-

Knocking within

-Hark! more knocking.
-Get on your nightgown, lest occasion call us,
-And show us to be watchers. Be not lost
-So poorly in your thoughts.
-
- -MACBETH -
-To know my deed, 'twere best not know myself.
-

Knocking within

-Wake Duncan with thy knocking! I would thou couldst!
-

Exeunt

-
-

SCENE III. The same.

-

-Knocking within. Enter a Porter -
- -Porter -
-Here's a knocking indeed! If a
-man were porter of hell-gate, he should have
-old turning the key.
-

Knocking within

-Knock,
-knock, knock! Who's there, i' the name of
-Beelzebub? Here's a farmer, that hanged
-himself on the expectation of plenty: come in
-time; have napkins enow about you; here
-you'll sweat for't.
-

Knocking within

-Knock,
-knock! Who's there, in the other devil's
-name? Faith, here's an equivocator, that could
-swear in both the scales against either scale;
-who committed treason enough for God's sake,
-yet could not equivocate to heaven: O, come
-in, equivocator.
-

Knocking within

-Knock,
-knock, knock! Who's there? Faith, here's an
-English tailor come hither, for stealing out of
-a French hose: come in, tailor; here you may
-roast your goose.
-

Knocking within

-Knock,
-knock; never at quiet! What are you? But
-this place is too cold for hell. I'll devil-porter
-it no further: I had thought to have let in
-some of all professions that go the primrose
-way to the everlasting bonfire.
-

Knocking within

-Anon, anon! I pray you, remember the porter.
-

Opens the gate

-

Enter MACDUFF and LENNOX

-
- -MACDUFF -
-Was it so late, friend, ere you went to bed,
-That you do lie so late?
-
- -Porter -
-'Faith sir, we were carousing till the
-second cock: and drink, sir, is a great
-provoker of three things.
-
- -MACDUFF -
-What three things does drink especially provoke?
-
- -Porter -
-Marry, sir, nose-painting, sleep, and
-urine. Lechery, sir, it provokes, and unprovokes;
-it provokes the desire, but it takes
-away the performance: therefore, much drink
-may be said to be an equivocator with lechery:
-it makes him, and it mars him; it sets
-him on, and it takes him off; it persuades him,
-and disheartens him; makes him stand to, and
-not stand to; in conclusion, equivocates him
-in a sleep, and, giving him the lie, leaves him.
-
- -MACDUFF -
-I believe drink gave thee the lie last night.
-
- -Porter -
-That it did, sir, i' the very throat on
-me: but I requited him for his lie; and, I
-think, being too strong for him, though he took
-up my legs sometime, yet I made a shift to cast
-him.
-
- -MACDUFF -
-Is thy master stirring?
-

Enter MACBETH

-Our knocking has awaked him; here he comes.
-
- -LENNOX -
-Good morrow, noble sir.
-
- -MACBETH -
-Good morrow, both.
-
- -MACDUFF -
-Is the king stirring, worthy thane?
-
- -MACBETH -
-Not yet.
-
- -MACDUFF -
-He did command me to call timely on him:
-I have almost slipp'd the hour.
-
- -MACBETH -
-I'll bring you to him.
-
- -MACDUFF -
-I know this is a joyful trouble to you;
-But yet 'tis one.
-
- -MACBETH -
-The labour we delight in physics pain.
-This is the door.
-
- -MACDUFF -
- I'll make so bold to call,
-For 'tis my limited service.
-

Exit

-
- -LENNOX -
-Goes the king hence to-day?
-
- -MACBETH -
-He does: he did appoint so.
-
- -LENNOX -
-The night has been unruly: where we lay,
-Our chimneys were blown down; and, as they say,
-Lamentings heard i' the air; strange screams of death,
-And prophesying with accents terrible
-Of dire combustion and confused events
-New hatch'd to the woeful time: the obscure bird
-Clamour'd the livelong night: some say, the earth
-Was feverous and did shake.
-
- -MACBETH -
-'Twas a rough night.
-
- -LENNOX -
-My young remembrance cannot parallel
-A fellow to it.
-

Re-enter MACDUFF

-
- -MACDUFF -
-O horror, horror, horror! Tongue nor heart
-Cannot conceive nor name thee!
-
- -MACBETH - -LENNOX -
-What's the matter.
-
- -MACDUFF -
-Confusion now hath made his masterpiece!
-Most sacrilegious murder hath broke ope
-The Lord's anointed temple, and stole thence
-The life o' the building!
-
- -MACBETH -
-What is 't you say? the life?
-
- -LENNOX -
-Mean you his majesty?
-
- -MACDUFF -
-Approach the chamber, and destroy your sight
-With a new Gorgon: do not bid me speak;
-See, and then speak yourselves.
-

Exeunt MACBETH and LENNOX

-Awake, awake!
-Ring the alarum-bell. Murder and treason!
-Banquo and Donalbain! Malcolm! awake!
-Shake off this downy sleep, death's counterfeit,
-And look on death itself! up, up, and see
-The great doom's image! Malcolm! Banquo!
-As from your graves rise up, and walk like sprites,
-To countenance this horror! Ring the bell.
-

Bell rings

-

Enter LADY MACBETH

-
- -LADY MACBETH -
-What's the business,
-That such a hideous trumpet calls to parley
-The sleepers of the house? speak, speak!
-
- -MACDUFF -
-O gentle lady,
-'Tis not for you to hear what I can speak:
-The repetition, in a woman's ear,
-Would murder as it fell.
-

Enter BANQUO

-O Banquo, Banquo,
-Our royal master 's murder'd!
-
- -LADY MACBETH -
-Woe, alas!
-What, in our house?
-
- -BANQUO -
-Too cruel any where.
-Dear Duff, I prithee, contradict thyself,
-And say it is not so.
-

Re-enter MACBETH and LENNOX, with ROSS

-
- -MACBETH -
-Had I but died an hour before this chance,
-I had lived a blessed time; for, from this instant,
-There 's nothing serious in mortality:
-All is but toys: renown and grace is dead;
-The wine of life is drawn, and the mere lees
-Is left this vault to brag of.
-

Enter MALCOLM and DONALBAIN

-
- -DONALBAIN -
-What is amiss?
-
- -MACBETH -
- You are, and do not know't:
-The spring, the head, the fountain of your blood
-Is stopp'd; the very source of it is stopp'd.
-
- -MACDUFF -
-Your royal father 's murder'd.
-
- -MALCOLM -
-O, by whom?
-
- -LENNOX -
-Those of his chamber, as it seem'd, had done 't:
-Their hands and faces were an badged with blood;
-So were their daggers, which unwiped we found
-Upon their pillows:
-They stared, and were distracted; no man's life
-Was to be trusted with them.
-
- -MACBETH -
-O, yet I do repent me of my fury,
-That I did kill them.
-
- -MACDUFF -
-Wherefore did you so?
-
- -MACBETH -
-Who can be wise, amazed, temperate and furious,
-Loyal and neutral, in a moment? No man:
-The expedition my violent love
-Outrun the pauser, reason. Here lay Duncan,
-His silver skin laced with his golden blood;
-And his gash'd stabs look'd like a breach in nature
-For ruin's wasteful entrance: there, the murderers,
-Steep'd in the colours of their trade, their daggers
-Unmannerly breech'd with gore: who could refrain,
-That had a heart to love, and in that heart
-Courage to make 's love kno wn?
-
- -LADY MACBETH -
-Help me hence, ho!
-
- -MACDUFF -
-Look to the lady.
-
- -MALCOLM -
-[Aside to DONALBAIN] Why do we hold our tongues,
-That most may claim this argument for ours?
-
- -DONALBAIN -
-[Aside to MALCOLM] What should be spoken here,
-where our fate,
-Hid in an auger-hole, may rush, and seize us?
-Let 's away;
-Our tears are not yet brew'd.
-
- -MALCOLM -
-[Aside to DONALBAIN] Nor our strong sorrow
-Upon the foot of motion.
-
- -BANQUO -
-Look to the lady:
-

LADY MACBETH is carried out

-And when we have our naked frailties hid,
-That suffer in exposure, let us meet,
-And question this most bloody piece of work,
-To know it further. Fears and scruples shake us:
-In the great hand of God I stand; and thence
-Against the undivulged pretence I fight
-Of treasonous malice.
-
- -MACDUFF -
-And so do I.
-
- -ALL -
-So all.
-
- -MACBETH -
-Let's briefly put on manly readiness,
-And meet i' the hall together.
-
- -ALL -
-Well contented.
-

Exeunt all but Malcolm and Donalbain.

-
- -MALCOLM -
-What will you do? Let's not consort with them:
-To show an unfelt sorrow is an office
-Which the false man does easy. I'll to England.
-
- -DONALBAIN -
-To Ireland, I; our separated fortune
-Shall keep us both the safer: where we are,
-There's daggers in men's smiles: the near in blood,
-The nearer bloody.
-
- -MALCOLM -
- This murderous shaft that's shot
-Hath not yet lighted, and our safest way
-Is to avoid the aim. Therefore, to horse;
-And let us not be dainty of leave-taking,
-But shift away: there's warrant in that theft
-Which steals itself, when there's no mercy left.
-

Exeunt

-
-

SCENE IV. Outside Macbeth's castle.

-

-Enter ROSS and an old Man -
- -Old Man -
-Threescore and ten I can remember well:
-Within the volume of which time I have seen
-Hours dreadful and things strange; but this sore night
-Hath trifled former knowings.
-
- -ROSS -
-Ah, good father,
-Thou seest, the heavens, as troubled with man's act,
-Threaten his bloody stage: by the clock, 'tis day,
-And yet dark night strangles the travelling lamp:
-Is't night's predominance, or the day's shame,
-That darkness does the face of earth entomb,
-When living light should kiss it?
-
- -Old Man -
-'Tis unnatural,
-Even like the deed that's done. On Tuesday last,
-A falcon, towering in her pride of place,
-Was by a mousing owl hawk'd at and kill'd.
-
- -ROSS -
-And Duncan's horses--a thing most strange and certain--
-Beauteous and swift, the minions of their race,
-Turn'd wild in nature, broke their stalls, flung out,
-Contending 'gainst obedience, as they would make
-War with mankind.
-
- -Old Man -
-'Tis said they eat each other.
-
- -ROSS -
-They did so, to the amazement of mine eyes
-That look'd upon't. Here comes the good Macduff.
-

Enter MACDUFF

-How goes the world, sir, now?
-
- -MACDUFF -
-Why, see you not?
-
- -ROSS -
-Is't known who did this more than bloody deed?
-
- -MACDUFF -
-Those that Macbeth hath slain.
-
- -ROSS -
-Alas, the day!
-What good could they pretend?
-
- -MACDUFF -
-They were suborn'd:
-Malcolm and Donalbain, the king's two sons,
-Are stol'n away and fled; which puts upon them
-Suspicion of the deed.
-
- -ROSS -
-'Gainst nature still!
-Thriftless ambition, that wilt ravin up
-Thine own life's means! Then 'tis most like
-The sovereignty will fall upon Macbeth.
-
- -MACDUFF -
-He is already named, and gone to Scone
-To be invested.
-
- -ROSS -
- Where is Duncan's body?
-
- -MACDUFF -
-Carried to Colmekill,
-The sacred storehouse of his predecessors,
-And guardian of their bones.
-
- -ROSS -
-Will you to Scone?
-
- -MACDUFF -
-No, cousin, I'll to Fife.
-
- -ROSS -
-Well, I will thither.
-
- -MACDUFF -
-Well, may you see things well done there: adieu!
-Lest our old robes sit easier than our new!
-
- -ROSS -
-Farewell, father.
-
- -Old Man -
-God's benison go with you; and with those
-That would make good of bad, and friends of foes!
-

Exeunt

-

-

ACT III

-

SCENE I. Forres. The palace.

-

-Enter BANQUO -
- -BANQUO -
-Thou hast it now: king, Cawdor, Glamis, all,
-As the weird women promised, and, I fear,
-Thou play'dst most foully for't: yet it was said
-It should not stand in thy posterity,
-But that myself should be the root and father
-Of many kings. If there come truth from them--
-As upon thee, Macbeth, their speeches shine--
-Why, by the verities on thee made good,
-May they not be my oracles as well,
-And set me up in hope? But hush! no more.
-

Sennet sounded. Enter MACBETH, as king, LADY MACBETH, as queen, LENNOX, ROSS, Lords, Ladies, and Attendants

-
- -MACBETH -
-Here's our chief guest.
-
- -LADY MACBETH -
-If he had been forgotten,
-It had been as a gap in our great feast,
-And all-thing unbecoming.
-
- -MACBETH -
-To-night we hold a solemn supper sir,
-And I'll request your presence.
-
- -BANQUO -
-Let your highness
-Command upon me; to the which my duties
-Are with a most indissoluble tie
-For ever knit.
-
- -MACBETH -
- Ride you this afternoon?
-
- -BANQUO -
-Ay, my good lord.
-
- -MACBETH -
-We should have else desired your good advice,
-Which still hath been both grave and prosperous,
-In this day's council; but we'll take to-morrow.
-Is't far you ride?
-
- -BANQUO -
-As far, my lord, as will fill up the time
-'Twixt this and supper: go not my horse the better,
-I must become a borrower of the night
-For a dark hour or twain.
-
- -MACBETH -
-Fail not our feast.
-
- -BANQUO -
-My lord, I will not.
-
- -MACBETH -
-We hear, our bloody cousins are bestow'd
-In England and in Ireland, not confessing
-Their cruel parricide, filling their hearers
-With strange invention: but of that to-morrow,
-When therewithal we shall have cause of state
-Craving us jointly. Hie you to horse: adieu,
-Till you return at night. Goes Fleance with you?
-
- -BANQUO -
-Ay, my good lord: our time does call upon 's.
-
- -MACBETH -
-I wish your horses swift and sure of foot;
-And so I do commend you to their backs. Farewell.
-

Exit BANQUO

-Let every man be master of his time
-Till seven at night: to make society
-The sweeter welcome, we will keep ourself
-Till supper-time alone: while then, God be with you!
-

Exeunt all but MACBETH, and an attendant

-Sirrah, a word with you: attend those men
-Our pleasure?
-
- -ATTENDANT -
-They are, my lord, without the palace gate.
-
- -MACBETH -
-Bring them before us.
-

Exit Attendant

-To be thus is nothing;
-But to be safely thus.--Our fears in Banquo
-Stick deep; and in his royalty of nature
-Reigns that which would be fear'd: 'tis much he dares;
-And, to that dauntless temper of his mind,
-He hath a wisdom that doth guide his valour
-To act in safety. There is none but he
-Whose being I do fear: and, under him,
-My Genius is rebuked; as, it is said,
-Mark Antony's was by Caesar. He chid the sisters
-When first they put the name of king upon me,
-And bade them speak to him: then prophet-like
-They hail'd him father to a line of kings:
-Upon my head they placed a fruitless crown,
-And put a barren sceptre in my gripe,
-Thence to be wrench'd with an unlineal hand,
-No son of mine succeeding. If 't be so,
-For Banquo's issue have I filed my mind;
-For them the gracious Duncan have I murder'd;
-Put rancours in the vessel of my peace
-Only for them; and mine eternal jewel
-Given to the common enemy of man,
-To make them kings, the seed of Banquo kings!
-Rather than so, come fate into the list.
-And champion me to the utterance! Who's there!
-

Re-enter Attendant, with two Murderers

-Now go to the door, and stay there till we call.
-

Exit Attendant

-Was it not yesterday we spoke together?
-
- -First Murderer -
-It was, so please your highness.
-
- -MACBETH -
-Well then, now
-Have you consider'd of my speeches? Know
-That it was he in the times past which held you
-So under fortune, which you thought had been
-Our innocent self: this I made good to you
-In our last conference, pass'd in probation with you,
-How you were borne in hand, how cross'd,
-the instruments,
-Who wrought with them, and all things else that might
-To half a soul and to a notion crazed
-Say 'Thus did Banquo.'
-
- -First Murderer -
-You made it known to us.
-
- -MACBETH -
-I did so, and went further, which is now
-Our point of second meeting. Do you find
-Your patience so predominant in your nature
-That you can let this go? Are you so gospell'd
-To pray for this good man and for his issue,
-Whose heavy hand hath bow'd you to the grave
-And beggar'd yours for ever?
-
- -First Murderer -
-We are men, my liege.
-
- -MACBETH -
-Ay, in the catalogue ye go for men;
-As hounds and greyhounds, mongrels, spaniels, curs,
-Shoughs, water-rugs and demi-wolves, are clept
-All by the name of dogs: the valued file
-Distinguishes the swift, the slow, the subtle,
-The housekeeper, the hunter, every one
-According to the gift which bounteous nature
-Hath in him closed; whereby he does receive
-Particular addition. from the bill
-That writes them all alike: and so of men.
-Now, if you have a station in the file,
-Not i' the worst rank of manhood, say 't;
-And I will put that business in your bosoms,
-Whose execution takes your enemy off,
-Grapples you to the heart and love of us,
-Who wear our health but sickly in his life,
-Which in his death were perfect.
-
- -Second Murderer -
-I am one, my liege,
-Whom the vile blows and buffets of the world
-Have so incensed that I am reckless what
-I do to spite the world.
-
- -First Murderer -
-And I another
-So weary with disasters, tugg'd with fortune,
-That I would set my lie on any chance,
-To mend it, or be rid on't.
-
- -MACBETH -
-Both of you
-Know Banquo was your enemy.
-
- -Both Murderers -
-True, my lord.
-
- -MACBETH -
-So is he mine; and in such bloody distance,
-That every minute of his being thrusts
-Against my near'st of life: and though I could
-With barefaced power sweep him from my sight
-And bid my will avouch it, yet I must not,
-For certain friends that are both his and mine,
-Whose loves I may not drop, but wail his fall
-Who I myself struck down; and thence it is,
-That I to your assistance do make love,
-Masking the business from the common eye
-For sundry weighty reasons.
-
- -Second Murderer -
-We shall, my lord,
-Perform what you command us.
-
- -First Murderer -
-Though our lives--
-
- -MACBETH -
-Your spirits shine through you. Within this hour at most
-I will advise you where to plant yourselves;
-Acquaint you with the perfect spy o' the time,
-The moment on't; for't must be done to-night,
-And something from the palace; always thought
-That I require a clearness: and with him--
-To leave no rubs nor botches in the work--
-Fleance his son, that keeps him company,
-Whose absence is no less material to me
-Than is his father's, must embrace the fate
-Of that dark hour. Resolve yourselves apart:
-I'll come to you anon.
-
- -Both Murderers -
-We are resolved, my lord.
-
- -MACBETH -
-I'll call upon you straight: abide within.
-

Exeunt Murderers

-It is concluded. Banquo, thy soul's flight,
-If it find heaven, must find it out to-night.
-

Exit

-
-

SCENE II. The palace.

-

-Enter LADY MACBETH and a Servant -
- -LADY MACBETH -
-Is Banquo gone from court?
-
- -Servant -
-Ay, madam, but returns again to-night.
-
- -LADY MACBETH -
-Say to the king, I would attend his leisure
-For a few words.
-
- -Servant -
- Madam, I will.
-

Exit

-
- -LADY MACBETH -
-Nought's had, all's spent,
-Where our desire is got without content:
-'Tis safer to be that which we destroy
-Than by destruction dwell in doubtful joy.
-

Enter MACBETH

-How now, my lord! why do you keep alone,
-Of sorriest fancies your companions making,
-Using those thoughts which should indeed have died
-With them they think on? Things without all remedy
-Should be without regard: what's done is done.
-
- -MACBETH -
-We have scotch'd the snake, not kill'd it:
-She'll close and be herself, whilst our poor malice
-Remains in danger of her former tooth.
-But let the frame of things disjoint, both the
-worlds suffer,
-Ere we will eat our meal in fear and sleep
-In the affliction of these terrible dreams
-That shake us nightly: better be with the dead,
-Whom we, to gain our peace, have sent to peace,
-Than on the torture of the mind to lie
-In restless ecstasy. Duncan is in his grave;
-After life's fitful fever he sleeps well;
-Treason has done his worst: nor steel, nor poison,
-Malice domestic, foreign levy, nothing,
-Can touch him further.
-
- -LADY MACBETH -
-Come on;
-Gentle my lord, sleek o'er your rugged looks;
-Be bright and jovial among your guests to-night.
-
- -MACBETH -
-So shall I, love; and so, I pray, be you:
-Let your remembrance apply to Banquo;
-Present him eminence, both with eye and tongue:
-Unsafe the while, that we
-Must lave our honours in these flattering streams,
-And make our faces vizards to our hearts,
-Disguising what they are.
-
- -LADY MACBETH -
-You must leave this.
-
- -MACBETH -
-O, full of scorpions is my mind, dear wife!
-Thou know'st that Banquo, and his Fleance, lives.
-
- -LADY MACBETH -
-But in them nature's copy's not eterne.
-
- -MACBETH -
-There's comfort yet; they are assailable;
-Then be thou jocund: ere the bat hath flown
-His cloister'd flight, ere to black Hecate's summons
-The shard-borne beetle with his drowsy hums
-Hath rung night's yawning peal, there shall be done
-A deed of dreadful note.
-
- -LADY MACBETH -
-What's to be done?
-
- -MACBETH -
-Be innocent of the knowledge, dearest chuck,
-Till thou applaud the deed. Come, seeling night,
-Scarf up the tender eye of pitiful day;
-And with thy bloody and invisible hand
-Cancel and tear to pieces that great bond
-Which keeps me pale! Light thickens; and the crow
-Makes wing to the rooky wood:
-Good things of day begin to droop and drowse;
-While night's black agents to their preys do rouse.
-Thou marvell'st at my words: but hold thee still;
-Things bad begun make strong themselves by ill.
-So, prithee, go with me.
-

Exeunt

-
-

SCENE III. A park near the palace.

-

-Enter three Murderers -
- -First Murderer -
-But who did bid thee join with us?
-
- -Third Murderer -
-Macbeth.
-
- -Second Murderer -
-He needs not our mistrust, since he delivers
-Our offices and what we have to do
-To the direction just.
-
- -First Murderer -
-Then stand with us.
-The west yet glimmers with some streaks of day:
-Now spurs the lated traveller apace
-To gain the timely inn; and near approaches
-The subject of our watch.
-
- -Third Murderer -
-Hark! I hear horses.
-
- -BANQUO -
-[Within] Give us a light there, ho!
-
- -Second Murderer -
-Then 'tis he: the rest
-That are within the note of expectation
-Already are i' the court.
-
- -First Murderer -
-His horses go about.
-
- -Third Murderer -
-Almost a mile: but he does usually,
-So all men do, from hence to the palace gate
-Make it their walk.
-
- -Second Murderer -
-A light, a light!
-

Enter BANQUO, and FLEANCE with a torch

-
- -Third Murderer -
-'Tis he.
-
- -First Murderer -
-Stand to't.
-
- -BANQUO -
-It will be rain to-night.
-
- -First Murderer -
-Let it come down.
-

They set upon BANQUO

-
- -BANQUO -
-O, treachery! Fly, good Fleance, fly, fly, fly!
-Thou mayst revenge. O slave!
-

Dies. FLEANCE escapes

-
- -Third Murderer -
-Who did strike out the light?
-
- -First Murderer -
-Wast not the way?
-
- -Third Murderer -
-There's but one down; the son is fled.
-
- -Second Murderer -
-We have lost
-Best half of our affair.
-
- -First Murderer -
-Well, let's away, and say how much is done.
-

Exeunt

-
-

SCENE IV. The same. Hall in the palace.

-

-A banquet prepared. Enter MACBETH, LADY MACBETH, ROSS, LENNOX, Lords, and Attendants -
- -MACBETH -
-You know your own degrees; sit down: at first
-And last the hearty welcome.
-
- -Lords -
-Thanks to your majesty.
-
- -MACBETH -
-Ourself will mingle with society,
-And play the humble host.
-Our hostess keeps her state, but in best time
-We will require her welcome.
-
- -LADY MACBETH -
-Pronounce it for me, sir, to all our friends;
-For my heart speaks they are welcome.
-

First Murderer appears at the door

-
- -MACBETH -
-See, they encounter thee with their hearts' thanks.
-Both sides are even: here I'll sit i' the midst:
-Be large in mirth; anon we'll drink a measure
-The table round.
-

Approaching the door

-There's blood on thy face.
-
- -First Murderer -
-'Tis Banquo's then.
-
- -MACBETH -
-'Tis better thee without than he within.
-Is he dispatch'd?
-
- -First Murderer -
-My lord, his throat is cut; that I did for him.
-
- -MACBETH -
-Thou art the best o' the cut-throats: yet he's good
-That did the like for Fleance: if thou didst it,
-Thou art the nonpareil.
-
- -First Murderer -
-Most royal sir,
-Fleance is 'scaped.
-
- -MACBETH -
-Then comes my fit again: I had else been perfect,
-Whole as the marble, founded as the rock,
-As broad and general as the casing air:
-But now I am cabin'd, cribb'd, confined, bound in
-To saucy doubts and fears. But Banquo's safe?
-
- -First Murderer -
-Ay, my good lord: safe in a ditch he bides,
-With twenty trenched gashes on his head;
-The least a death to nature.
-
- -MACBETH -
-Thanks for that:
-There the grown serpent lies; the worm that's fled
-Hath nature that in time will venom breed,
-No teeth for the present. Get thee gone: to-morrow
-We'll hear, ourselves, again.
-

Exit Murderer

-
- -LADY MACBETH -
-My royal lord,
-You do not give the cheer: the feast is sold
-That is not often vouch'd, while 'tis a-making,
-'Tis given with welcome: to feed were best at home;
-From thence the sauce to meat is ceremony;
-Meeting were bare without it.
-
- -MACBETH -
-Sweet remembrancer!
-Now, good digestion wait on appetite,
-And health on both!
-
- -LENNOX -
-May't please your highness sit.
-

The GHOST OF BANQUO enters, and sits in MACBETH's place

-
- -MACBETH -
-Here had we now our country's honour roof'd,
-Were the graced person of our Banquo present;
-Who may I rather challenge for unkindness
-Than pity for mischance!
-
- -ROSS -
-His absence, sir,
-Lays blame upon his promise. Please't your highness
-To grace us with your royal company.
-
- -MACBETH -
-The table's full.
-
- -LENNOX -
- Here is a place reserved, sir.
-
- -MACBETH -
-Where?
-
- -LENNOX -
-Here, my good lord. What is't that moves your highness?
-
- -MACBETH -
-Which of you have done this?
-
- -Lords -
-What, my good lord?
-
- -MACBETH -
-Thou canst not say I did it: never shake
-Thy gory locks at me.
-
- -ROSS -
-Gentlemen, rise: his highness is not well.
-
- -LADY MACBETH -
-Sit, worthy friends: my lord is often thus,
-And hath been from his youth: pray you, keep seat;
-The fit is momentary; upon a thought
-He will again be well: if much you note him,
-You shall offend him and extend his passion:
-Feed, and regard him not. Are you a man?
-
- -MACBETH -
-Ay, and a bold one, that dare look on that
-Which might appal the devil.
-
- -LADY MACBETH -
-O proper stuff!
-This is the very painting of your fear:
-This is the air-drawn dagger which, you said,
-Led you to Duncan. O, these flaws and starts,
-Impostors to true fear, would well become
-A woman's story at a winter's fire,
-Authorized by her grandam. Shame itself!
-Why do you make such faces? When all's done,
-You look but on a stool.
-
- -MACBETH -
-Prithee, see there! behold! look! lo!
-how say you?
-Why, what care I? If thou canst nod, speak too.
-If charnel-houses and our graves must send
-Those that we bury back, our monuments
-Shall be the maws of kites.
-

GHOST OF BANQUO vanishes

-
- -LADY MACBETH -
-What, quite unmann'd in folly?
-
- -MACBETH -
-If I stand here, I saw him.
-
- -LADY MACBETH -
-Fie, for shame!
-
- -MACBETH -
-Blood hath been shed ere now, i' the olden time,
-Ere human statute purged the gentle weal;
-Ay, and since too, murders have been perform'd
-Too terrible for the ear: the times have been,
-That, when the brains were out, the man would die,
-And there an end; but now they rise again,
-With twenty mortal murders on their crowns,
-And push us from our stools: this is more strange
-Than such a murder is.
-
- -LADY MACBETH -
-My worthy lord,
-Your noble friends do lack you.
-
- -MACBETH -
-I do forget.
-Do not muse at me, my most worthy friends,
-I have a strange infirmity, which is nothing
-To those that know me. Come, love and health to all;
-Then I'll sit down. Give me some wine; fill full.
-I drink to the general joy o' the whole table,
-And to our dear friend Banquo, whom we miss;
-Would he were here! to all, and him, we thirst,
-And all to all.
-
- -Lords -
- Our duties, and the pledge.
-

Re-enter GHOST OF BANQUO

-
- -MACBETH -
-Avaunt! and quit my sight! let the earth hide thee!
-Thy bones are marrowless, thy blood is cold;
-Thou hast no speculation in those eyes
-Which thou dost glare with!
-
- -LADY MACBETH -
-Think of this, good peers,
-But as a thing of custom: 'tis no other;
-Only it spoils the pleasure of the time.
-
- -MACBETH -
-What man dare, I dare:
-Approach thou like the rugged Russian bear,
-The arm'd rhinoceros, or the Hyrcan tiger;
-Take any shape but that, and my firm nerves
-Shall never tremble: or be alive again,
-And dare me to the desert with thy sword;
-If trembling I inhabit then, protest me
-The baby of a girl. Hence, horrible shadow!
-Unreal mockery, hence!
-

GHOST OF BANQUO vanishes

-Why, so: being gone,
-I am a man again. Pray you, sit still.
-
- -LADY MACBETH -
-You have displaced the mirth, broke the good meeting,
-With most admired disorder.
-
- -MACBETH -
-Can such things be,
-And overcome us like a summer's cloud,
-Without our special wonder? You make me strange
-Even to the disposition that I owe,
-When now I think you can behold such sights,
-And keep the natural ruby of your cheeks,
-When mine is blanched with fear.
-
- -ROSS -
-What sights, my lord?
-
- -LADY MACBETH -
-I pray you, speak not; he grows worse and worse;
-Question enrages him. At once, good night:
-Stand not upon the order of your going,
-But go at once.
-
- -LENNOX -
- Good night; and better health
-Attend his majesty!
-
- -LADY MACBETH -
-A kind good night to all!
-

Exeunt all but MACBETH and LADY MACBETH

-
- -MACBETH -
-It will have blood; they say, blood will have blood:
-Stones have been known to move and trees to speak;
-Augurs and understood relations have
-By magot-pies and choughs and rooks brought forth
-The secret'st man of blood. What is the night?
-
- -LADY MACBETH -
-Almost at odds with morning, which is which.
-
- -MACBETH -
-How say'st thou, that Macduff denies his person
-At our great bidding?
-
- -LADY MACBETH -
-Did you send to him, sir?
-
- -MACBETH -
-I hear it by the way; but I will send:
-There's not a one of them but in his house
-I keep a servant fee'd. I will to-morrow,
-And betimes I will, to the weird sisters:
-More shall they speak; for now I am bent to know,
-By the worst means, the worst. For mine own good,
-All causes shall give way: I am in blood
-Stepp'd in so far that, should I wade no more,
-Returning were as tedious as go o'er:
-Strange things I have in head, that will to hand;
-Which must be acted ere they may be scann'd.
-
- -LADY MACBETH -
-You lack the season of all natures, sleep.
-
- -MACBETH -
-Come, we'll to sleep. My strange and self-abuse
-Is the initiate fear that wants hard use:
-We are yet but young in deed.
-

Exeunt

-
-

SCENE V. A Heath.

-

-Thunder. Enter the three Witches meeting HECATE -
- -First Witch -
-Why, how now, Hecate! you look angerly.
-
- -HECATE -
-Have I not reason, beldams as you are,
-Saucy and overbold? How did you dare
-To trade and traffic with Macbeth
-In riddles and affairs of death;
-And I, the mistress of your charms,
-The close contriver of all harms,
-Was never call'd to bear my part,
-Or show the glory of our art?
-And, which is worse, all you have done
-Hath been but for a wayward son,
-Spiteful and wrathful, who, as others do,
-Loves for his own ends, not for you.
-But make amends now: get you gone,
-And at the pit of Acheron
-Meet me i' the morning: thither he
-Will come to know his destiny:
-Your vessels and your spells provide,
-Your charms and every thing beside.
-I am for the air; this night I'll spend
-Unto a dismal and a fatal end:
-Great business must be wrought ere noon:
-Upon the corner of the moon
-There hangs a vaporous drop profound;
-I'll catch it ere it come to ground:
-And that distill'd by magic sleights
-Shall raise such artificial sprites
-As by the strength of their illusion
-Shall draw him on to his confusion:
-He shall spurn fate, scorn death, and bear
-He hopes 'bove wisdom, grace and fear:
-And you all know, security
-Is mortals' chiefest enemy.
-

Music and a song within: 'Come away, come away,' & c

-Hark! I am call'd; my little spirit, see,
-Sits in a foggy cloud, and stays for me.
-

Exit

-
- -First Witch -
-Come, let's make haste; she'll soon be back again.
-

Exeunt

-
-

SCENE VI. Forres. The palace.

-

-Enter LENNOX and another Lord -
- -LENNOX -
-My former speeches have but hit your thoughts,
-Which can interpret further: only, I say,
-Things have been strangely borne. The
-gracious Duncan
-Was pitied of Macbeth: marry, he was dead:
-And the right-valiant Banquo walk'd too late;
-Whom, you may say, if't please you, Fleance kill'd,
-For Fleance fled: men must not walk too late.
-Who cannot want the thought how monstrous
-It was for Malcolm and for Donalbain
-To kill their gracious father? damned fact!
-How it did grieve Macbeth! did he not straight
-In pious rage the two delinquents tear,
-That were the slaves of drink and thralls of sleep?
-Was not that nobly done? Ay, and wisely too;
-For 'twould have anger'd any heart alive
-To hear the men deny't. So that, I say,
-He has borne all things well: and I do think
-That had he Duncan's sons under his key--
-As, an't please heaven, he shall not--they
-should find
-What 'twere to kill a father; so should Fleance.
-But, peace! for from broad words and 'cause he fail'd
-His presence at the tyrant's feast, I hear
-Macduff lives in disgrace: sir, can you tell
-Where he bestows himself?
-
- -Lord -
-The son of Duncan,
-From whom this tyrant holds the due of birth
-Lives in the English court, and is received
-Of the most pious Edward with such grace
-That the malevolence of fortune nothing
-Takes from his high respect: thither Macduff
-Is gone to pray the holy king, upon his aid
-To wake Northumberland and warlike Siward:
-That, by the help of these--with Him above
-To ratify the work--we may again
-Give to our tables meat, sleep to our nights,
-Free from our feasts and banquets bloody knives,
-Do faithful homage and receive free honours:
-All which we pine for now: and this report
-Hath so exasperate the king that he
-Prepares for some attempt of war.
-
- -LENNOX -
-Sent he to Macduff?
-
- -Lord -
-He did: and with an absolute 'Sir, not I,'
-The cloudy messenger turns me his back,
-And hums, as who should say 'You'll rue the time
-That clogs me with this answer.'
-
- -LENNOX -
-And that well might
-Advise him to a caution, to hold what distance
-His wisdom can provide. Some holy angel
-Fly to the court of England and unfold
-His message ere he come, that a swift blessing
-May soon return to this our suffering country
-Under a hand accursed!
-
- -Lord -
-I'll send my prayers with him.
-

Exeunt

-

-

ACT IV

-

SCENE I. A cavern. In the middle, a boiling cauldron.

-

-Thunder. Enter the three Witches -
- -First Witch -
-Thrice the brinded cat hath mew'd.
-
- -Second Witch -
-Thrice and once the hedge-pig whined.
-
- -Third Witch -
-Harpier cries 'Tis time, 'tis time.
-
- -First Witch -
-Round about the cauldron go;
-In the poison'd entrails throw.
-Toad, that under cold stone
-Days and nights has thirty-one
-Swelter'd venom sleeping got,
-Boil thou first i' the charmed pot.
-
- -ALL -
-Double, double toil and trouble;
-Fire burn, and cauldron bubble.
-
- -Second Witch -
-Fillet of a fenny snake,
-In the cauldron boil and bake;
-Eye of newt and toe of frog,
-Wool of bat and tongue of dog,
-Adder's fork and blind-worm's sting,
-Lizard's leg and owlet's wing,
-For a charm of powerful trouble,
-Like a hell-broth boil and bubble.
-
- -ALL -
-Double, double toil and trouble;
-Fire burn and cauldron bubble.
-
- -Third Witch -
-Scale of dragon, tooth of wolf,
-Witches' mummy, maw and gulf
-Of the ravin'd salt-sea shark,
-Root of hemlock digg'd i' the dark,
-Liver of blaspheming Jew,
-Gall of goat, and slips of yew
-Silver'd in the moon's eclipse,
-Nose of Turk and Tartar's lips,
-Finger of birth-strangled babe
-Ditch-deliver'd by a drab,
-Make the gruel thick and slab:
-Add thereto a tiger's chaudron,
-For the ingredients of our cauldron.
-
- -ALL -
-Double, double toil and trouble;
-Fire burn and cauldron bubble.
-
- -Second Witch -
-Cool it with a baboon's blood,
-Then the charm is firm and good.
-

Enter HECATE to the other three Witches

-
- -HECATE -
-O well done! I commend your pains;
-And every one shall share i' the gains;
-And now about the cauldron sing,
-Live elves and fairies in a ring,
-Enchanting all that you put in.
-

Music and a song: 'Black spirits,' & c

-

HECATE retires

-
- -Second Witch -
-By the pricking of my thumbs,
-Something wicked this way comes.
-Open, locks,
-Whoever knocks!
-

Enter MACBETH

-
- -MACBETH -
-How now, you secret, black, and midnight hags!
-What is't you do?
-
- -ALL -
- A deed without a name.
-
- -MACBETH -
-I conjure you, by that which you profess,
-Howe'er you come to know it, answer me:
-Though you untie the winds and let them fight
-Against the churches; though the yesty waves
-Confound and swallow navigation up;
-Though bladed corn be lodged and trees blown down;
-Though castles topple on their warders' heads;
-Though palaces and pyramids do slope
-Their heads to their foundations; though the treasure
-Of nature's germens tumble all together,
-Even till destruction sicken; answer me
-To what I ask you.
-
- -First Witch -
- Speak.
-
- -Second Witch -
-Demand.
-
- -Third Witch -
-We'll answer.
-
- -First Witch -
-Say, if thou'dst rather hear it from our mouths,
-Or from our masters?
-
- -MACBETH -
-Call 'em; let me see 'em.
-
- -First Witch -
-Pour in sow's blood, that hath eaten
-Her nine farrow; grease that's sweaten
-From the murderer's gibbet throw
-Into the flame.
-
- -ALL -
- Come, high or low;
-Thyself and office deftly show!
-

Thunder. First Apparition: an armed Head

-
- -MACBETH -
-Tell me, thou unknown power,--
-
- -First Witch -
-He knows thy thought:
-Hear his speech, but say thou nought.
-
- -First Apparition -
-Macbeth! Macbeth! Macbeth! beware Macduff;
-Beware the thane of Fife. Dismiss me. Enough.
-

Descends

-
- -MACBETH -
-Whate'er thou art, for thy good caution, thanks;
-Thou hast harp'd my fear aright: but one
-word more,--
-
- -First Witch -
-He will not be commanded: here's another,
-More potent than the first.
-

Thunder. Second Apparition: A bloody Child

-
- -Second Apparition -
-Macbeth! Macbeth! Macbeth!
-
- -MACBETH -
-Had I three ears, I'ld hear thee.
-
- -Second Apparition -
-Be bloody, bold, and resolute; laugh to scorn
-The power of man, for none of woman born
-Shall harm Macbeth.
-

Descends

-
- -MACBETH -
-Then live, Macduff: what need I fear of thee?
-But yet I'll make assurance double sure,
-And take a bond of fate: thou shalt not live;
-That I may tell pale-hearted fear it lies,
-And sleep in spite of thunder.
-

Thunder. Third Apparition: a Child crowned, with a tree in his hand

-What is this
-That rises like the issue of a king,
-And wears upon his baby-brow the round
-And top of sovereignty?
-
- -ALL -
-Listen, but speak not to't.
-
- -Third Apparition -
-Be lion-mettled, proud; and take no care
-Who chafes, who frets, or where conspirers are:
-Macbeth shall never vanquish'd be until
-Great Birnam wood to high Dunsinane hill
-Shall come against him.
-

Descends

-
- -MACBETH -
-That will never be
-Who can impress the forest, bid the tree
-Unfix his earth-bound root? Sweet bodements! good!
-Rebellion's head, rise never till the wood
-Of Birnam rise, and our high-placed Macbeth
-Shall live the lease of nature, pay his breath
-To time and mortal custom. Yet my heart
-Throbs to know one thing: tell me, if your art
-Can tell so much: shall Banquo's issue ever
-Reign in this kingdom?
-
- -ALL -
-Seek to know no more.
-
- -MACBETH -
-I will be satisfied: deny me this,
-And an eternal curse fall on you! Let me know.
-Why sinks that cauldron? and what noise is this?
-

Hautboys

-
- -First Witch -
-Show!
-
- -Second Witch -
-Show!
-
- -Third Witch -
-Show!
-
- -ALL -
-Show his eyes, and grieve his heart;
-Come like shadows, so depart!
-

A show of Eight Kings, the last with a glass in his hand; GHOST OF BANQUO following

-
- -MACBETH -
-Thou art too like the spirit of Banquo: down!
-Thy crown does sear mine eye-balls. And thy hair,
-Thou other gold-bound brow, is like the first.
-A third is like the former. Filthy hags!
-Why do you show me this? A fourth! Start, eyes!
-What, will the line stretch out to the crack of doom?
-Another yet! A seventh! I'll see no more:
-And yet the eighth appears, who bears a glass
-Which shows me many more; and some I see
-That two-fold balls and treble scepters carry:
-Horrible sight! Now, I see, 'tis true;
-For the blood-bolter'd Banquo smiles upon me,
-And points at them for his.
-

Apparitions vanish

-What, is this so?
-
- -First Witch -
-Ay, sir, all this is so: but why
-Stands Macbeth thus amazedly?
-Come, sisters, cheer we up his sprites,
-And show the best of our delights:
-I'll charm the air to give a sound,
-While you perform your antic round:
-That this great king may kindly say,
-Our duties did his welcome pay.
-

Music. The witches dance and then vanish, with HECATE

-
- -MACBETH -
-Where are they? Gone? Let this pernicious hour
-Stand aye accursed in the calendar!
-Come in, without there!
-

Enter LENNOX

-
- -LENNOX -
-What's your grace's will?
-
- -MACBETH -
-Saw you the weird sisters?
-
- -LENNOX -
-No, my lord.
-
- -MACBETH -
-Came they not by you?
-
- -LENNOX -
-No, indeed, my lord.
-
- -MACBETH -
-Infected be the air whereon they ride;
-And damn'd all those that trust them! I did hear
-The galloping of horse: who was't came by?
-
- -LENNOX -
-'Tis two or three, my lord, that bring you word
-Macduff is fled to England.
-
- -MACBETH -
-Fled to England!
-
- -LENNOX -
-Ay, my good lord.
-
- -MACBETH -
-Time, thou anticipatest my dread exploits:
-The flighty purpose never is o'ertook
-Unless the deed go with it; from this moment
-The very firstlings of my heart shall be
-The firstlings of my hand. And even now,
-To crown my thoughts with acts, be it thought and done:
-The castle of Macduff I will surprise;
-Seize upon Fife; give to the edge o' the sword
-His wife, his babes, and all unfortunate souls
-That trace him in his line. No boasting like a fool;
-This deed I'll do before this purpose cool.
-But no more sights!--Where are these gentlemen?
-Come, bring me where they are.
-

Exeunt

-
-

SCENE II. Fife. Macduff's castle.

-

-Enter LADY MACDUFF, her Son, and ROSS -
- -LADY MACDUFF -
-What had he done, to make him fly the land?
-
- -ROSS -
-You must have patience, madam.
-
- -LADY MACDUFF -
-He had none:
-His flight was madness: when our actions do not,
-Our fears do make us traitors.
-
- -ROSS -
-You know not
-Whether it was his wisdom or his fear.
-
- -LADY MACDUFF -
-Wisdom! to leave his wife, to leave his babes,
-His mansion and his titles in a place
-From whence himself does fly? He loves us not;
-He wants the natural touch: for the poor wren,
-The most diminutive of birds, will fight,
-Her young ones in her nest, against the owl.
-All is the fear and nothing is the love;
-As little is the wisdom, where the flight
-So runs against all reason.
-
- -ROSS -
-My dearest coz,
-I pray you, school yourself: but for your husband,
-He is noble, wise, judicious, and best knows
-The fits o' the season. I dare not speak
-much further;
-But cruel are the times, when we are traitors
-And do not know ourselves, when we hold rumour
-From what we fear, yet know not what we fear,
-But float upon a wild and violent sea
-Each way and move. I take my leave of you:
-Shall not be long but I'll be here again:
-Things at the worst will cease, or else climb upward
-To what they were before. My pretty cousin,
-Blessing upon you!
-
- -LADY MACDUFF -
-Father'd he is, and yet he's fatherless.
-
- -ROSS -
-I am so much a fool, should I stay longer,
-It would be my disgrace and your discomfort:
-I take my leave at once.
-

Exit

-
- -LADY MACDUFF -
-Sirrah, your father's dead;
-And what will you do now? How will you live?
-
- -Son -
-As birds do, mother.
-
- -LADY MACDUFF -
-What, with worms and flies?
-
- -Son -
-With what I get, I mean; and so do they.
-
- -LADY MACDUFF -
-Poor bird! thou'ldst never fear the net nor lime,
-The pitfall nor the gin.
-
- -Son -
-Why should I, mother? Poor birds they are not set for.
-My father is not dead, for all your saying.
-
- -LADY MACDUFF -
-Yes, he is dead; how wilt thou do for a father?
-
- -Son -
-Nay, how will you do for a husband?
-
- -LADY MACDUFF -
-Why, I can buy me twenty at any market.
-
- -Son -
-Then you'll buy 'em to sell again.
-
- -LADY MACDUFF -
-Thou speak'st with all thy wit: and yet, i' faith,
-With wit enough for thee.
-
- -Son -
-Was my father a traitor, mother?
-
- -LADY MACDUFF -
-Ay, that he was.
-
- -Son -
-What is a traitor?
-
- -LADY MACDUFF -
-Why, one that swears and lies.
-
- -Son -
-And be all traitors that do so?
-
- -LADY MACDUFF -
-Every one that does so is a traitor, and must be hanged.
-
- -Son -
-And must they all be hanged that swear and lie?
-
- -LADY MACDUFF -
-Every one.
-
- -Son -
-Who must hang them?
-
- -LADY MACDUFF -
-Why, the honest men.
-
- -Son -
-Then the liars and swearers are fools,
-for there are liars and swearers enow to beat
-the honest men and hang up them.
-
- -LADY MACDUFF -
-Now, God help thee, poor monkey!
-But how wilt thou do for a father?
-
- -Son -
-If he were dead, you'ld weep for
-him: if you would not, it were a good sign
-that I should quickly have a new father.
-
- -LADY MACDUFF -
-Poor prattler, how thou talk'st!
-

Enter a Messenger

-
- -Messenger -
-Bless you, fair dame! I am not to you known,
-Though in your state of honour I am perfect.
-I doubt some danger does approach you nearly:
-If you will take a homely man's advice,
-Be not found here; hence, with your little ones.
-To fright you thus, methinks, I am too savage;
-To do worse to you were fell cruelty,
-Which is too nigh your person. Heaven preserve you!
-I dare abide no longer.
-

Exit

-
- -LADY MACDUFF -
-Whither should I fly?
-I have done no harm. But I remember now
-I am in this earthly world; where to do harm
-Is often laudable, to do good sometime
-Accounted dangerous folly: why then, alas,
-Do I put up that womanly defence,
-To say I have done no harm?
-

Enter Murderers

-What are these faces?
-
- -First Murderer -
-Where is your husband?
-
- -LADY MACDUFF -
-I hope, in no place so unsanctified
-Where such as thou mayst find him.
-
- -First Murderer -
-He's a traitor.
-
- -Son -
-Thou liest, thou shag-hair'd villain!
-
- -First Murderer -
-What, you egg!
-

Stabbing him

-Young fry of treachery!
-
- -Son -
-He has kill'd me, mother:
-Run away, I pray you!
-

Dies

-

Exit LADY MACDUFF, crying 'Murder!' Exeunt Murderers, following her

-
-

SCENE III. England. Before the King's palace.

-

-Enter MALCOLM and MACDUFF -
- -MALCOLM -
-Let us seek out some desolate shade, and there
-Weep our sad bosoms empty.
-
- -MACDUFF -
-Let us rather
-Hold fast the mortal sword, and like good men
-Bestride our down-fall'n birthdom: each new morn
-New widows howl, new orphans cry, new sorrows
-Strike heaven on the face, that it resounds
-As if it felt with Scotland and yell'd out
-Like syllable of dolour.
-
- -MALCOLM -
-What I believe I'll wail,
-What know believe, and what I can redress,
-As I shall find the time to friend, I will.
-What you have spoke, it may be so perchance.
-This tyrant, whose sole name blisters our tongues,
-Was once thought honest: you have loved him well.
-He hath not touch'd you yet. I am young;
-but something
-You may deserve of him through me, and wisdom
-To offer up a weak poor innocent lamb
-To appease an angry god.
-
- -MACDUFF -
-I am not treacherous.
-
- -MALCOLM -
-But Macbeth is.
-A good and virtuous nature may recoil
-In an imperial charge. But I shall crave
-your pardon;
-That which you are my thoughts cannot transpose:
-Angels are bright still, though the brightest fell;
-Though all things foul would wear the brows of grace,
-Yet grace must still look so.
-
- -MACDUFF -
-I have lost my hopes.
-
- -MALCOLM -
-Perchance even there where I did find my doubts.
-Why in that rawness left you wife and child,
-Those precious motives, those strong knots of love,
-Without leave-taking? I pray you,
-Let not my jealousies be your dishonours,
-But mine own safeties. You may be rightly just,
-Whatever I shall think.
-
- -MACDUFF -
-Bleed, bleed, poor country!
-Great tyranny! lay thou thy basis sure,
-For goodness dare not cheque thee: wear thou
-thy wrongs;
-The title is affeer'd! Fare thee well, lord:
-I would not be the villain that thou think'st
-For the whole space that's in the tyrant's grasp,
-And the rich East to boot.
-
- -MALCOLM -
-Be not offended:
-I speak not as in absolute fear of you.
-I think our country sinks beneath the yoke;
-It weeps, it bleeds; and each new day a gash
-Is added to her wounds: I think withal
-There would be hands uplifted in my right;
-And here from gracious England have I offer
-Of goodly thousands: but, for all this,
-When I shall tread upon the tyrant's head,
-Or wear it on my sword, yet my poor country
-Shall have more vices than it had before,
-More suffer and more sundry ways than ever,
-By him that shall succeed.
-
- -MACDUFF -
-What should he be?
-
- -MALCOLM -
-It is myself I mean: in whom I know
-All the particulars of vice so grafted
-That, when they shall be open'd, black Macbeth
-Will seem as pure as snow, and the poor state
-Esteem him as a lamb, being compared
-With my confineless harms.
-
- -MACDUFF -
-Not in the legions
-Of horrid hell can come a devil more damn'd
-In evils to top Macbeth.
-
- -MALCOLM -
-I grant him bloody,
-Luxurious, avaricious, false, deceitful,
-Sudden, malicious, smacking of every sin
-That has a name: but there's no bottom, none,
-In my voluptuousness: your wives, your daughters,
-Your matrons and your maids, could not fill up
-The cistern of my lust, and my desire
-All continent impediments would o'erbear
-That did oppose my will: better Macbeth
-Than such an one to reign.
-
- -MACDUFF -
-Boundless intemperance
-In nature is a tyranny; it hath been
-The untimely emptying of the happy throne
-And fall of many kings. But fear not yet
-To take upon you what is yours: you may
-Convey your pleasures in a spacious plenty,
-And yet seem cold, the time you may so hoodwink.
-We have willing dames enough: there cannot be
-That vulture in you, to devour so many
-As will to greatness dedicate themselves,
-Finding it so inclined.
-
- -MALCOLM -
-With this there grows
-In my most ill-composed affection such
-A stanchless avarice that, were I king,
-I should cut off the nobles for their lands,
-Desire his jewels and this other's house:
-And my more-having would be as a sauce
-To make me hunger more; that I should forge
-Quarrels unjust against the good and loyal,
-Destroying them for wealth.
-
- -MACDUFF -
-This avarice
-Sticks deeper, grows with more pernicious root
-Than summer-seeming lust, and it hath been
-The sword of our slain kings: yet do not fear;
-Scotland hath foisons to fill up your will.
-Of your mere own: all these are portable,
-With other graces weigh'd.
-
- -MALCOLM -
-But I have none: the king-becoming graces,
-As justice, verity, temperance, stableness,
-Bounty, perseverance, mercy, lowliness,
-Devotion, patience, courage, fortitude,
-I have no relish of them, but abound
-In the division of each several crime,
-Acting it many ways. Nay, had I power, I should
-Pour the sweet milk of concord into hell,
-Uproar the universal peace, confound
-All unity on earth.
-
- -MACDUFF -
-O Scotland, Scotland!
-
- -MALCOLM -
-If such a one be fit to govern, speak:
-I am as I have spoken.
-
- -MACDUFF -
-Fit to govern!
-No, not to live. O nation miserable,
-With an untitled tyrant bloody-scepter'd,
-When shalt thou see thy wholesome days again,
-Since that the truest issue of thy throne
-By his own interdiction stands accursed,
-And does blaspheme his breed? Thy royal father
-Was a most sainted king: the queen that bore thee,
-Oftener upon her knees than on her feet,
-Died every day she lived. Fare thee well!
-These evils thou repeat'st upon thyself
-Have banish'd me from Scotland. O my breast,
-Thy hope ends here!
-
- -MALCOLM -
-Macduff, this noble passion,
-Child of integrity, hath from my soul
-Wiped the black scruples, reconciled my thoughts
-To thy good truth and honour. Devilish Macbeth
-By many of these trains hath sought to win me
-Into his power, and modest wisdom plucks me
-From over-credulous haste: but God above
-Deal between thee and me! for even now
-I put myself to thy direction, and
-Unspeak mine own detraction, here abjure
-The taints and blames I laid upon myself,
-For strangers to my nature. I am yet
-Unknown to woman, never was forsworn,
-Scarcely have coveted what was mine own,
-At no time broke my faith, would not betray
-The devil to his fellow and delight
-No less in truth than life: my first false speaking
-Was this upon myself: what I am truly,
-Is thine and my poor country's to command:
-Whither indeed, before thy here-approach,
-Old Siward, with ten thousand warlike men,
-Already at a point, was setting forth.
-Now we'll together; and the chance of goodness
-Be like our warranted quarrel! Why are you silent?
-
- -MACDUFF -
-Such welcome and unwelcome things at once
-'Tis hard to reconcile.
-

Enter a Doctor

-
- -MALCOLM -
-Well; more anon.--Comes the king forth, I pray you?
-
- -Doctor -
-Ay, sir; there are a crew of wretched souls
-That stay his cure: their malady convinces
-The great assay of art; but at his touch--
-Such sanctity hath heaven given his hand--
-They presently amend.
-
- -MALCOLM -
-I thank you, doctor.
-

Exit Doctor

-
- -MACDUFF -
-What's the disease he means?
-
- -MALCOLM -
-'Tis call'd the evil:
-A most miraculous work in this good king;
-Which often, since my here-remain in England,
-I have seen him do. How he solicits heaven,
-Himself best knows: but strangely-visited people,
-All swoln and ulcerous, pitiful to the eye,
-The mere despair of surgery, he cures,
-Hanging a golden stamp about their necks,
-Put on with holy prayers: and 'tis spoken,
-To the succeeding royalty he leaves
-The healing benediction. With this strange virtue,
-He hath a heavenly gift of prophecy,
-And sundry blessings hang about his throne,
-That speak him full of grace.
-

Enter ROSS

-
- -MACDUFF -
-See, who comes here?
-
- -MALCOLM -
-My countryman; but yet I know him not.
-
- -MACDUFF -
-My ever-gentle cousin, welcome hither.
-
- -MALCOLM -
-I know him now. Good God, betimes remove
-The means that makes us strangers!
-
- -ROSS -
-Sir, amen.
-
- -MACDUFF -
-Stands Scotland where it did?
-
- -ROSS -
-Alas, poor country!
-Almost afraid to know itself. It cannot
-Be call'd our mother, but our grave; where nothing,
-But who knows nothing, is once seen to smile;
-Where sighs and groans and shrieks that rend the air
-Are made, not mark'd; where violent sorrow seems
-A modern ecstasy; the dead man's knell
-Is there scarce ask'd for who; and good men's lives
-Expire before the flowers in their caps,
-Dying or ere they sicken.
-
- -MACDUFF -
-O, relation
-Too nice, and yet too true!
-
- -MALCOLM -
-What's the newest grief?
-
- -ROSS -
-That of an hour's age doth hiss the speaker:
-Each minute teems a new one.
-
- -MACDUFF -
-How does my wife?
-
- -ROSS -
-Why, well.
-
- -MACDUFF -
- And all my children?
-
- -ROSS -
-Well too.
-
- -MACDUFF -
-The tyrant has not batter'd at their peace?
-
- -ROSS -
-No; they were well at peace when I did leave 'em.
-
- -MACDUFF -
-But not a niggard of your speech: how goes't?
-
- -ROSS -
-When I came hither to transport the tidings,
-Which I have heavily borne, there ran a rumour
-Of many worthy fellows that were out;
-Which was to my belief witness'd the rather,
-For that I saw the tyrant's power a-foot:
-Now is the time of help; your eye in Scotland
-Would create soldiers, make our women fight,
-To doff their dire distresses.
-
- -MALCOLM -
-Be't their comfort
-We are coming thither: gracious England hath
-Lent us good Siward and ten thousand men;
-An older and a better soldier none
-That Christendom gives out.
-
- -ROSS -
-Would I could answer
-This comfort with the like! But I have words
-That would be howl'd out in the desert air,
-Where hearing should not latch them.
-
- -MACDUFF -
-What concern they?
-The general cause? or is it a fee-grief
-Due to some single breast?
-
- -ROSS -
-No mind that's honest
-But in it shares some woe; though the main part
-Pertains to you alone.
-
- -MACDUFF -
-If it be mine,
-Keep it not from me, quickly let me have it.
-
- -ROSS -
-Let not your ears despise my tongue for ever,
-Which shall possess them with the heaviest sound
-That ever yet they heard.
-
- -MACDUFF -
-Hum! I guess at it.
-
- -ROSS -
-Your castle is surprised; your wife and babes
-Savagely slaughter'd: to relate the manner,
-Were, on the quarry of these murder'd deer,
-To add the death of you.
-
- -MALCOLM -
-Merciful heaven!
-What, man! ne'er pull your hat upon your brows;
-Give sorrow words: the grief that does not speak
-Whispers the o'er-fraught heart and bids it break.
-
- -MACDUFF -
-My children too?
-
- -ROSS -
- Wife, children, servants, all
-That could be found.
-
- -MACDUFF -
-And I must be from thence!
-My wife kill'd too?
-
- -ROSS -
-I have said.
-
- -MALCOLM -
-Be comforted:
-Let's make us medicines of our great revenge,
-To cure this deadly grief.
-
- -MACDUFF -
-He has no children. All my pretty ones?
-Did you say all? O hell-kite! All?
-What, all my pretty chickens and their dam
-At one fell swoop?
-
- -MALCOLM -
-Dispute it like a man.
-
- -MACDUFF -
-I shall do so;
-But I must also feel it as a man:
-I cannot but remember such things were,
-That were most precious to me. Did heaven look on,
-And would not take their part? Sinful Macduff,
-They were all struck for thee! naught that I am,
-Not for their own demerits, but for mine,
-Fell slaughter on their souls. Heaven rest them now!
-
- -MALCOLM -
-Be this the whetstone of your sword: let grief
-Convert to anger; blunt not the heart, enrage it.
-
- -MACDUFF -
-O, I could play the woman with mine eyes
-And braggart with my tongue! But, gentle heavens,
-Cut short all intermission; front to front
-Bring thou this fiend of Scotland and myself;
-Within my sword's length set him; if he 'scape,
-Heaven forgive him too!
-
- -MALCOLM -
-This tune goes manly.
-Come, go we to the king; our power is ready;
-Our lack is nothing but our leave; Macbeth
-Is ripe for shaking, and the powers above
-Put on their instruments. Receive what cheer you may:
-The night is long that never finds the day.
-

Exeunt

-

-

ACT V

-

SCENE I. Dunsinane. Ante-room in the castle.

-

-Enter a Doctor of Physic and a Waiting-Gentlewoman -
- -Doctor -
-I have two nights watched with you, but can perceive
-no truth in your report. When was it she last walked?
-
- -Gentlewoman -
-Since his majesty went into the field, I have seen
-her rise from her bed, throw her night-gown upon
-her, unlock her closet, take forth paper, fold it,
-write upon't, read it, afterwards seal it, and again
-return to bed; yet all this while in a most fast sleep.
-
- -Doctor -
-A great perturbation in nature, to receive at once
-the benefit of sleep, and do the effects of
-watching! In this slumbery agitation, besides her
-walking and other actual performances, what, at any
-time, have you heard her say?
-
- -Gentlewoman -
-That, sir, which I will not report after her.
-
- -Doctor -
-You may to me: and 'tis most meet you should.
-
- -Gentlewoman -
-Neither to you nor any one; having no witness to
-confirm my speech.
-

Enter LADY MACBETH, with a taper

-Lo you, here she comes! This is her very guise;
-and, upon my life, fast asleep. Observe her; stand close.
-
- -Doctor -
-How came she by that light?
-
- -Gentlewoman -
-Why, it stood by her: she has light by her
-continually; 'tis her command.
-
- -Doctor -
-You see, her eyes are open.
-
- -Gentlewoman -
-Ay, but their sense is shut.
-
- -Doctor -
-What is it she does now? Look, how she rubs her hands.
-
- -Gentlewoman -
-It is an accustomed action with her, to seem thus
-washing her hands: I have known her continue in
-this a quarter of an hour.
-
- -LADY MACBETH -
-Yet here's a spot.
-
- -Doctor -
-Hark! she speaks: I will set down what comes from
-her, to satisfy my remembrance the more strongly.
-
- -LADY MACBETH -
-Out, damned spot! out, I say!--One: two: why,
-then, 'tis time to do't.--Hell is murky!--Fie, my
-lord, fie! a soldier, and afeard? What need we
-fear who knows it, when none can call our power to
-account?--Yet who would have thought the old man
-to have had so much blood in him.
-
- -Doctor -
-Do you mark that?
-
- -LADY MACBETH -
-The thane of Fife had a wife: where is she now?--
-What, will these hands ne'er be clean?--No more o'
-that, my lord, no more o' that: you mar all with
-this starting.
-
- -Doctor -
-Go to, go to; you have known what you should not.
-
- -Gentlewoman -
-She has spoke what she should not, I am sure of
-that: heaven knows what she has known.
-
- -LADY MACBETH -
-Here's the smell of the blood still: all the
-perfumes of Arabia will not sweeten this little
-hand. Oh, oh, oh!
-
- -Doctor -
-What a sigh is there! The heart is sorely charged.
-
- -Gentlewoman -
-I would not have such a heart in my bosom for the
-dignity of the whole body.
-
- -Doctor -
-Well, well, well,--
-
- -Gentlewoman -
-Pray God it be, sir.
-
- -Doctor -
-This disease is beyond my practise: yet I have known
-those which have walked in their sleep who have died
-holily in their beds.
-
- -LADY MACBETH -
-Wash your hands, put on your nightgown; look not so
-pale.--I tell you yet again, Banquo's buried; he
-cannot come out on's grave.
-
- -Doctor -
-Even so?
-
- -LADY MACBETH -
-To bed, to bed! there's knocking at the gate:
-come, come, come, come, give me your hand. What's
-done cannot be undone.--To bed, to bed, to bed!
-

Exit

-
- -Doctor -
-Will she go now to bed?
-
- -Gentlewoman -
-Directly.
-
- -Doctor -
-Foul whisperings are abroad: unnatural deeds
-Do breed unnatural troubles: infected minds
-To their deaf pillows will discharge their secrets:
-More needs she the divine than the physician.
-God, God forgive us all! Look after her;
-Remove from her the means of all annoyance,
-And still keep eyes upon her. So, good night:
-My mind she has mated, and amazed my sight.
-I think, but dare not speak.
-
- -Gentlewoman -
-Good night, good doctor.
-

Exeunt

-
-

SCENE II. The country near Dunsinane.

-

-Drum and colours. Enter MENTEITH, CAITHNESS, ANGUS, LENNOX, and Soldiers -
- -MENTEITH -
-The English power is near, led on by Malcolm,
-His uncle Siward and the good Macduff:
-Revenges burn in them; for their dear causes
-Would to the bleeding and the grim alarm
-Excite the mortified man.
-
- -ANGUS -
-Near Birnam wood
-Shall we well meet them; that way are they coming.
-
- -CAITHNESS -
-Who knows if Donalbain be with his brother?
-
- -LENNOX -
-For certain, sir, he is not: I have a file
-Of all the gentry: there is Siward's son,
-And many unrough youths that even now
-Protest their first of manhood.
-
- -MENTEITH -
-What does the tyrant?
-
- -CAITHNESS -
-Great Dunsinane he strongly fortifies:
-Some say he's mad; others that lesser hate him
-Do call it valiant fury: but, for certain,
-He cannot buckle his distemper'd cause
-Within the belt of rule.
-
- -ANGUS -
-Now does he feel
-His secret murders sticking on his hands;
-Now minutely revolts upbraid his faith-breach;
-Those he commands move only in command,
-Nothing in love: now does he feel his title
-Hang loose about him, like a giant's robe
-Upon a dwarfish thief.
-
- -MENTEITH -
-Who then shall blame
-His pester'd senses to recoil and start,
-When all that is within him does condemn
-Itself for being there?
-
- -CAITHNESS -
-Well, march we on,
-To give obedience where 'tis truly owed:
-Meet we the medicine of the sickly weal,
-And with him pour we in our country's purge
-Each drop of us.
-
- -LENNOX -
- Or so much as it needs,
-To dew the sovereign flower and drown the weeds.
-Make we our march towards Birnam.
-

Exeunt, marching

-
-

SCENE III. Dunsinane. A room in the castle.

-

-Enter MACBETH, Doctor, and Attendants -
- -MACBETH -
-Bring me no more reports; let them fly all:
-Till Birnam wood remove to Dunsinane,
-I cannot taint with fear. What's the boy Malcolm?
-Was he not born of woman? The spirits that know
-All mortal consequences have pronounced me thus:
-'Fear not, Macbeth; no man that's born of woman
-Shall e'er have power upon thee.' Then fly,
-false thanes,
-And mingle with the English epicures:
-The mind I sway by and the heart I bear
-Shall never sag with doubt nor shake with fear.
-

Enter a Servant

-The devil damn thee black, thou cream-faced loon!
-Where got'st thou that goose look?
-
- -Servant -
-There is ten thousand--
-
- -MACBETH -
-Geese, villain!
-
- -Servant -
-Soldiers, sir.
-
- -MACBETH -
-Go prick thy face, and over-red thy fear,
-Thou lily-liver'd boy. What soldiers, patch?
-Death of thy soul! those linen cheeks of thine
-Are counsellors to fear. What soldiers, whey-face?
-
- -Servant -
-The English force, so please you.
-
- -MACBETH -
-Take thy face hence.
-

Exit Servant

-Seyton!--I am sick at heart,
-When I behold--Seyton, I say!--This push
-Will cheer me ever, or disseat me now.
-I have lived long enough: my way of life
-Is fall'n into the sear, the yellow leaf;
-And that which should accompany old age,
-As honour, love, obedience, troops of friends,
-I must not look to have; but, in their stead,
-Curses, not loud but deep, mouth-honour, breath,
-Which the poor heart would fain deny, and dare not. Seyton!
-

Enter SEYTON

-
- -SEYTON -
-What is your gracious pleasure?
-
- -MACBETH -
-What news more?
-
- -SEYTON -
-All is confirm'd, my lord, which was reported.
-
- -MACBETH -
-I'll fight till from my bones my flesh be hack'd.
-Give me my armour.
-
- -SEYTON -
-'Tis not needed yet.
-
- -MACBETH -
-I'll put it on.
-Send out more horses; skirr the country round;
-Hang those that talk of fear. Give me mine armour.
-How does your patient, doctor?
-
- -Doctor -
-Not so sick, my lord,
-As she is troubled with thick coming fancies,
-That keep her from her rest.
-
- -MACBETH -
-Cure her of that.
-Canst thou not minister to a mind diseased,
-Pluck from the memory a rooted sorrow,
-Raze out the written troubles of the brain
-And with some sweet oblivious antidote
-Cleanse the stuff'd bosom of that perilous stuff
-Which weighs upon the heart?
-
- -Doctor -
-Therein the patient
-Must minister to himself.
-
- -MACBETH -
-Throw physic to the dogs; I'll none of it.
-Come, put mine armour on; give me my staff.
-Seyton, send out. Doctor, the thanes fly from me.
-Come, sir, dispatch. If thou couldst, doctor, cast
-The water of my land, find her disease,
-And purge it to a sound and pristine health,
-I would applaud thee to the very echo,
-That should applaud again.--Pull't off, I say.--
-What rhubarb, cyme, or what purgative drug,
-Would scour these English hence? Hear'st thou of them?
-
- -Doctor -
-Ay, my good lord; your royal preparation
-Makes us hear something.
-
- -MACBETH -
-Bring it after me.
-I will not be afraid of death and bane,
-Till Birnam forest come to Dunsinane.
-
- -Doctor -
-[Aside] Were I from Dunsinane away and clear,
-Profit again should hardly draw me here.
-

Exeunt

-
-

SCENE IV. Country near Birnam wood.

-

-Drum and colours. Enter MALCOLM, SIWARD and YOUNG SIWARD, MACDUFF, MENTEITH, CAITHNESS, ANGUS, LENNOX, ROSS, and Soldiers, marching -
- -MALCOLM -
-Cousins, I hope the days are near at hand
-That chambers will be safe.
-
- -MENTEITH -
-We doubt it nothing.
-
- -SIWARD -
-What wood is this before us?
-
- -MENTEITH -
-The wood of Birnam.
-
- -MALCOLM -
-Let every soldier hew him down a bough
-And bear't before him: thereby shall we shadow
-The numbers of our host and make discovery
-Err in report of us.
-
- -Soldiers -
-It shall be done.
-
- -SIWARD -
-We learn no other but the confident tyrant
-Keeps still in Dunsinane, and will endure
-Our setting down before 't.
-
- -MALCOLM -
-'Tis his main hope:
-For where there is advantage to be given,
-Both more and less have given him the revolt,
-And none serve with him but constrained things
-Whose hearts are absent too.
-
- -MACDUFF -
-Let our just censures
-Attend the true event, and put we on
-Industrious soldiership.
-
- -SIWARD -
-The time approaches
-That will with due decision make us know
-What we shall say we have and what we owe.
-Thoughts speculative their unsure hopes relate,
-But certain issue strokes must arbitrate:
-Towards which advance the war.
-

Exeunt, marching

-
-

SCENE V. Dunsinane. Within the castle.

-

-Enter MACBETH, SEYTON, and Soldiers, with drum and colours -
- -MACBETH -
-Hang out our banners on the outward walls;
-The cry is still 'They come:' our castle's strength
-Will laugh a siege to scorn: here let them lie
-Till famine and the ague eat them up:
-Were they not forced with those that should be ours,
-We might have met them dareful, beard to beard,
-And beat them backward home.
-

A cry of women within

-What is that noise?
-
- -SEYTON -
-It is the cry of women, my good lord.
-

Exit

-
- -MACBETH -
-I have almost forgot the taste of fears;
-The time has been, my senses would have cool'd
-To hear a night-shriek; and my fell of hair
-Would at a dismal treatise rouse and stir
-As life were in't: I have supp'd full with horrors;
-Direness, familiar to my slaughterous thoughts
-Cannot once start me.
-

Re-enter SEYTON

-Wherefore was that cry?
-
- -SEYTON -
-The queen, my lord, is dead.
-
- -MACBETH -
-She should have died hereafter;
-There would have been a time for such a word.
-To-morrow, and to-morrow, and to-morrow,
-Creeps in this petty pace from day to day
-To the last syllable of recorded time,
-And all our yesterdays have lighted fools
-The way to dusty death. Out, out, brief candle!
-Life's but a walking shadow, a poor player
-That struts and frets his hour upon the stage
-And then is heard no more: it is a tale
-Told by an idiot, full of sound and fury,
-Signifying nothing.
-

Enter a Messenger

-Thou comest to use thy tongue; thy story quickly.
-
- -Messenger -
-Gracious my lord,
-I should report that which I say I saw,
-But know not how to do it.
-
- -MACBETH -
-Well, say, sir.
-
- -Messenger -
-As I did stand my watch upon the hill,
-I look'd toward Birnam, and anon, methought,
-The wood began to move.
-
- -MACBETH -
-Liar and slave!
-
- -Messenger -
-Let me endure your wrath, if't be not so:
-Within this three mile may you see it coming;
-I say, a moving grove.
-
- -MACBETH -
-If thou speak'st false,
-Upon the next tree shalt thou hang alive,
-Till famine cling thee: if thy speech be sooth,
-I care not if thou dost for me as much.
-I pull in resolution, and begin
-To doubt the equivocation of the fiend
-That lies like truth: 'Fear not, till Birnam wood
-Do come to Dunsinane:' and now a wood
-Comes toward Dunsinane. Arm, arm, and out!
-If this which he avouches does appear,
-There is nor flying hence nor tarrying here.
-I gin to be aweary of the sun,
-And wish the estate o' the world were now undone.
-Ring the alarum-bell! Blow, wind! come, wrack!
-At least we'll die with harness on our back.
-

Exeunt

-
-

SCENE VI. Dunsinane. Before the castle.

-

-Drum and colours. Enter MALCOLM, SIWARD, MACDUFF, and their Army, with boughs -
- -MALCOLM -
-Now near enough: your leafy screens throw down.
-And show like those you are. You, worthy uncle,
-Shall, with my cousin, your right-noble son,
-Lead our first battle: worthy Macduff and we
-Shall take upon 's what else remains to do,
-According to our order.
-
- -SIWARD -
-Fare you well.
-Do we but find the tyrant's power to-night,
-Let us be beaten, if we cannot fight.
-
- -MACDUFF -
-Make all our trumpets speak; give them all breath,
-Those clamorous harbingers of blood and death.
-

Exeunt

-
-

SCENE VII. Another part of the field.

-

-Alarums. Enter MACBETH -
- -MACBETH -
-They have tied me to a stake; I cannot fly,
-But, bear-like, I must fight the course. What's he
-That was not born of woman? Such a one
-Am I to fear, or none.
-

Enter YOUNG SIWARD

-
- -YOUNG SIWARD -
-What is thy name?
-
- -MACBETH -
- Thou'lt be afraid to hear it.
-
- -YOUNG SIWARD -
-No; though thou call'st thyself a hotter name
-Than any is in hell.
-
- -MACBETH -
-My name's Macbeth.
-
- -YOUNG SIWARD -
-The devil himself could not pronounce a title
-More hateful to mine ear.
-
- -MACBETH -
-No, nor more fearful.
-
- -YOUNG SIWARD -
-Thou liest, abhorred tyrant; with my sword
-I'll prove the lie thou speak'st.
-

They fight and YOUNG SIWARD is slain

-
- -MACBETH -
-Thou wast born of woman
-But swords I smile at, weapons laugh to scorn,
-Brandish'd by man that's of a woman born.
-

Exit

-

Alarums. Enter MACDUFF

-
- -MACDUFF -
-That way the noise is. Tyrant, show thy face!
-If thou be'st slain and with no stroke of mine,
-My wife and children's ghosts will haunt me still.
-I cannot strike at wretched kerns, whose arms
-Are hired to bear their staves: either thou, Macbeth,
-Or else my sword with an unbatter'd edge
-I sheathe again undeeded. There thou shouldst be;
-By this great clatter, one of greatest note
-Seems bruited. Let me find him, fortune!
-And more I beg not.
-

Exit. Alarums

-

Enter MALCOLM and SIWARD

-
- -SIWARD -
-This way, my lord; the castle's gently render'd:
-The tyrant's people on both sides do fight;
-The noble thanes do bravely in the war;
-The day almost itself professes yours,
-And little is to do.
-
- -MALCOLM -
-We have met with foes
-That strike beside us.
-
- -SIWARD -
-Enter, sir, the castle.
-

Exeunt. Alarums

-
-

SCENE VIII. Another part of the field.

-

-Enter MACBETH -
- -MACBETH -
-Why should I play the Roman fool, and die
-On mine own sword? whiles I see lives, the gashes
-Do better upon them.
-

Enter MACDUFF

-
- -MACDUFF -
-Turn, hell-hound, turn!
-
- -MACBETH -
-Of all men else I have avoided thee:
-But get thee back; my soul is too much charged
-With blood of thine already.
-
- -MACDUFF -
-I have no words:
-My voice is in my sword: thou bloodier villain
-Than terms can give thee out!
-

They fight

-
- -MACBETH -
-Thou losest labour:
-As easy mayst thou the intrenchant air
-With thy keen sword impress as make me bleed:
-Let fall thy blade on vulnerable crests;
-I bear a charmed life, which must not yield,
-To one of woman born.
-
- -MACDUFF -
-Despair thy charm;
-And let the angel whom thou still hast served
-Tell thee, Macduff was from his mother's womb
-Untimely ripp'd.
-
- -MACBETH -
-Accursed be that tongue that tells me so,
-For it hath cow'd my better part of man!
-And be these juggling fiends no more believed,
-That palter with us in a double sense;
-That keep the word of promise to our ear,
-And break it to our hope. I'll not fight with thee.
-
- -MACDUFF -
-Then yield thee, coward,
-And live to be the show and gaze o' the time:
-We'll have thee, as our rarer monsters are,
-Painted on a pole, and underwrit,
-'Here may you see the tyrant.'
-
- -MACBETH -
-I will not yield,
-To kiss the ground before young Malcolm's feet,
-And to be baited with the rabble's curse.
-Though Birnam wood be come to Dunsinane,
-And thou opposed, being of no woman born,
-Yet I will try the last. Before my body
-I throw my warlike shield. Lay on, Macduff,
-And damn'd be him that first cries, 'Hold, enough!'
-

Exeunt, fighting. Alarums

-

Retreat. Flourish. Enter, with drum and colours, MALCOLM, SIWARD, ROSS, the other Thanes, and Soldiers

-
- -MALCOLM -
-I would the friends we miss were safe arrived.
-
- -SIWARD -
-Some must go off: and yet, by these I see,
-So great a day as this is cheaply bought.
-
- -MALCOLM -
-Macduff is missing, and your noble son.
-
- -ROSS -
-Your son, my lord, has paid a soldier's debt:
-He only lived but till he was a man;
-The which no sooner had his prowess confirm'd
-In the unshrinking station where he fought,
-But like a man he died.
-
- -SIWARD -
-Then he is dead?
-
- -ROSS -
-Ay, and brought off the field: your cause of sorrow
-Must not be measured by his worth, for then
-It hath no end.
-
- -SIWARD -
- Had he his hurts before?
-
- -ROSS -
-Ay, on the front.
-
- -SIWARD -
- Why then, God's soldier be he!
-Had I as many sons as I have hairs,
-I would not wish them to a fairer death:
-And so, his knell is knoll'd.
-
- -MALCOLM -
-He's worth more sorrow,
-And that I'll spend for him.
-
- -SIWARD -
-He's worth no more
-They say he parted well, and paid his score:
-And so, God be with him! Here comes newer comfort.
-

Re-enter MACDUFF, with MACBETH's head

-
- -MACDUFF -
-Hail, king! for so thou art: behold, where stands
-The usurper's cursed head: the time is free:
-I see thee compass'd with thy kingdom's pearl,
-That speak my salutation in their minds;
-Whose voices I desire aloud with mine:
-Hail, King of Scotland!
-
- -ALL -
-Hail, King of Scotland!
-

Flourish

-
- -MALCOLM -
-We shall not spend a large expense of time
-Before we reckon with your several loves,
-And make us even with you. My thanes and kinsmen,
-Henceforth be earls, the first that ever Scotland
-In such an honour named. What's more to do,
-Which would be planted newly with the time,
-As calling home our exiled friends abroad
-That fled the snares of watchful tyranny;
-Producing forth the cruel ministers
-Of this dead butcher and his fiend-like queen,
-Who, as 'tis thought, by self and violent hands
-Took off her life; this, and what needful else
-That calls upon us, by the grace of Grace,
-We will perform in measure, time and place:
-So, thanks to all at once and to each one,
-Whom we invite to see us crown'd at Scone.
-

Flourish. Exeunt

- - diff --git a/testing/marionette/harness/marionette_harness/www/modal_dialogs.html b/testing/marionette/harness/marionette_harness/www/modal_dialogs.html deleted file mode 100644 index 8da5b92a76..0000000000 --- a/testing/marionette/harness/marionette_harness/www/modal_dialogs.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - Marionette Test - - - - Open an alert dialog. - Open a confirm dialog. - Open a prompt dialog. - Add an onbeforeunload handler. - Make text appear. -
-
-
- - diff --git a/testing/marionette/harness/marionette_harness/www/nestedElements.html b/testing/marionette/harness/marionette_harness/www/nestedElements.html deleted file mode 100644 index 618bf3231b..0000000000 --- a/testing/marionette/harness/marionette_harness/www/nestedElements.html +++ /dev/null @@ -1,9 +0,0 @@ - -hello world -hello worldhello world - - -hello worldhello worldhello world diff --git a/testing/marionette/harness/marionette_harness/www/rectangles.html b/testing/marionette/harness/marionette_harness/www/rectangles.html deleted file mode 100644 index 59871c6de6..0000000000 --- a/testing/marionette/harness/marionette_harness/www/rectangles.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - Rectangles - - - -
r1
-
r2
-
r3
- - diff --git a/testing/marionette/harness/marionette_harness/www/resultPage.html b/testing/marionette/harness/marionette_harness/www/resultPage.html deleted file mode 100644 index 342e9930bd..0000000000 --- a/testing/marionette/harness/marionette_harness/www/resultPage.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - We Arrive Here - - - - -
- -
- - - diff --git a/testing/marionette/harness/marionette_harness/www/scroll.html b/testing/marionette/harness/marionette_harness/www/scroll.html deleted file mode 100644 index 8a654bb50b..0000000000 --- a/testing/marionette/harness/marionette_harness/www/scroll.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - -
-
    -
  • line1
  • -
  • line2
  • -
  • line3
  • -
  • line4
  • -
  • line5
  • -
  • line6
  • -
  • line7
  • -
  • line8
  • -
  • line9
  • -
-
- Clicked: -
- - diff --git a/testing/marionette/harness/marionette_harness/www/scroll2.html b/testing/marionette/harness/marionette_harness/www/scroll2.html deleted file mode 100644 index bd00f0e221..0000000000 --- a/testing/marionette/harness/marionette_harness/www/scroll2.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -
    -
  • -
  • -
  • Text
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
- - diff --git a/testing/marionette/harness/marionette_harness/www/scroll3.html b/testing/marionette/harness/marionette_harness/www/scroll3.html deleted file mode 100644 index b615e38c34..0000000000 --- a/testing/marionette/harness/marionette_harness/www/scroll3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - -



























































































































































- -



- -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 -
























































































































































- - diff --git a/testing/marionette/harness/marionette_harness/www/scroll4.html b/testing/marionette/harness/marionette_harness/www/scroll4.html deleted file mode 100644 index ce0df03132..0000000000 --- a/testing/marionette/harness/marionette_harness/www/scroll4.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - -


































































































- -


































































































- - diff --git a/testing/marionette/harness/marionette_harness/www/scroll5.html b/testing/marionette/harness/marionette_harness/www/scroll5.html deleted file mode 100644 index 3dd00721e6..0000000000 --- a/testing/marionette/harness/marionette_harness/www/scroll5.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - -
-
-
-
- Clicked: -
- - diff --git a/testing/marionette/harness/marionette_harness/www/shim.js b/testing/marionette/harness/marionette_harness/www/shim.js deleted file mode 100644 index 2a74e69492..0000000000 --- a/testing/marionette/harness/marionette_harness/www/shim.js +++ /dev/null @@ -1,282 +0,0 @@ -/** -* 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; - } - - var starttouch; // The Touch object that we started with - var target; // The element the touch is currently over - var 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 - var 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 (var i = 0; i < e.changedTouches.length; i++) { - var 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 (var i = 0; i < e.changedTouches.length; i++) { - var 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 - var dx = Math.abs(touch.screenX - starttouch.screenX); - var dy = Math.abs(touch.screenY - starttouch.screenY); - if (dx > MouseEventShim.dragThresholdX || - dy > MouseEventShim.dragThresholdY) { - emitclick = false; - } - - var tracking = MouseEventShim.trackMouseMoves && - !MouseEventShim.capturing; - - 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? - var oldtarget = target; - var 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 (var 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 (var e = newtarget; !contains(e, oldtarget); e = e.parentNode) { - emitEvent('mouseenter', e, touch, oldtarget); - } - } - - function emitEvent(type, target, touch, relatedTarget) { - var synthetic = document.createEvent('MouseEvents'); - var bubbles = (type !== 'mouseenter' && type !== 'mouseleave'); - var 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; - } - } -}()); - -var 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: function(e) { - if (e.isTrusted) // XXX: Are real events always trusted? - return e.timeStamp; - else - 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: function(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/test.html b/testing/marionette/harness/marionette_harness/www/test.html deleted file mode 100644 index 053ff171da..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Marionette Test - - -

Test Page

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

Test Page

- - - - - - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/testPageSource.html b/testing/marionette/harness/marionette_harness/www/testPageSource.html deleted file mode 100644 index f19b9d30cd..0000000000 --- a/testing/marionette/harness/marionette_harness/www/testPageSource.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - -PageSource Test - - -

Check the PageSource - - diff --git a/testing/marionette/harness/marionette_harness/www/testPageSource.xml b/testing/marionette/harness/marionette_harness/www/testPageSource.xml deleted file mode 100644 index 1480a1f38e..0000000000 --- a/testing/marionette/harness/marionette_harness/www/testPageSource.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - baz - - diff --git a/testing/marionette/harness/marionette_harness/www/testPageSourceWithUnicodeChars.html b/testing/marionette/harness/marionette_harness/www/testPageSourceWithUnicodeChars.html deleted file mode 100644 index d16cf52c83..0000000000 --- a/testing/marionette/harness/marionette_harness/www/testPageSourceWithUnicodeChars.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/testSize.html b/testing/marionette/harness/marionette_harness/www/testSize.html deleted file mode 100644 index 1df27ad23c..0000000000 --- a/testing/marionette/harness/marionette_harness/www/testSize.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - Test page for element size - - -

Let's get the size of some really cool link

- - diff --git a/testing/marionette/harness/marionette_harness/www/test_accessibility.html b/testing/marionette/harness/marionette_harness/www/test_accessibility.html deleted file mode 100644 index 8cc9fd6493..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_accessibility.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - -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_carets_columns.html b/testing/marionette/harness/marionette_harness/www/test_carets_columns.html deleted file mode 100644 index 4952361085..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_columns.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - -
-
-

Before image 1

-

-

After image 1

-

Before image 2

-

-

After image 2

-
-
- - diff --git a/testing/marionette/harness/marionette_harness/www/test_carets_cursor.html b/testing/marionette/harness/marionette_harness/www/test_carets_cursor.html deleted file mode 100644 index fdbd6fe7a8..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_cursor.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Marionette tests for AccessibleCaret in cursor mode - - - -
- - -
-
-
- - -
-
-
ABCDEFGHI
- - diff --git a/testing/marionette/harness/marionette_harness/www/test_carets_display_none.html b/testing/marionette/harness/marionette_harness/www/test_carets_display_none.html deleted file mode 100644 index 766f320011..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_display_none.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - -
ABC DEF GHI
- - diff --git a/testing/marionette/harness/marionette_harness/www/test_carets_iframe.html b/testing/marionette/harness/marionette_harness/www/test_carets_iframe.html deleted file mode 100644 index f6e6df9ba9..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_iframe.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - Marionette tests for AccessibleCaret in selection mode (iframe) - - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/test_carets_longtext.html b/testing/marionette/harness/marionette_harness/www/test_carets_longtext.html deleted file mode 100644 index 7e2495509b..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_longtext.html +++ /dev/null @@ -1,9 +0,0 @@ - - - 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/test_carets_multipleline.html b/testing/marionette/harness/marionette_harness/www/test_carets_multipleline.html deleted file mode 100644 index ff46a954ba..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_multipleline.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - 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/test_carets_multiplerange.html b/testing/marionette/harness/marionette_harness/www/test_carets_multiplerange.html deleted file mode 100644 index 394630c1fa..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_multiplerange.html +++ /dev/null @@ -1,19 +0,0 @@ - - - -

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/test_carets_selection.html b/testing/marionette/harness/marionette_harness/www/test_carets_selection.html deleted file mode 100644 index f58b92fbff..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_carets_selection.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - Marionette tests for AccessibleCaret in selection mode - - - -
- - -
-
-
- - -
-
-
-
-
ABC DEF GHI
-
-
ABC DEF GHI
-
-
Non-selectable
- - diff --git a/testing/marionette/harness/marionette_harness/www/test_clearing.html b/testing/marionette/harness/marionette_harness/www/test_clearing.html deleted file mode 100644 index 2aa3c6a21f..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_clearing.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - -
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 deleted file mode 100644 index dccc2c6acd..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_dynamic.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - diff --git a/testing/marionette/harness/marionette_harness/www/test_iframe.html b/testing/marionette/harness/marionette_harness/www/test_iframe.html deleted file mode 100644 index 7ed88665c5..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_iframe.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -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 deleted file mode 100644 index c836fc6e45..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_inner_iframe.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - -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 deleted file mode 100644 index b4482183ea..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_nested_iframe.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - -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 deleted file mode 100644 index 62e4ad0473..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_oop_1.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - -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 deleted file mode 100644 index 05aca5adba..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_oop_2.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - -OOP Test Frame 2 - - -

OOP Test Frame 2

- Hello! - - - diff --git a/testing/marionette/harness/marionette_harness/www/test_shadow_dom.html b/testing/marionette/harness/marionette_harness/www/test_shadow_dom.html deleted file mode 100644 index 3ee893e6d5..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_shadow_dom.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - -Marionette Test - - -
-
- - - diff --git a/testing/marionette/harness/marionette_harness/www/test_windows.html b/testing/marionette/harness/marionette_harness/www/test_windows.html deleted file mode 100644 index da1fd799ec..0000000000 --- a/testing/marionette/harness/marionette_harness/www/test_windows.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - XHTML Test Page - - -

Open new window

- - - diff --git a/testing/marionette/harness/marionette_harness/www/white.png b/testing/marionette/harness/marionette_harness/www/white.png deleted file mode 100644 index 8a68c11548..0000000000 Binary files a/testing/marionette/harness/marionette_harness/www/white.png and /dev/null differ diff --git a/testing/marionette/harness/marionette_harness/www/windowHandles.html b/testing/marionette/harness/marionette_harness/www/windowHandles.html deleted file mode 100644 index 165526c8ac..0000000000 --- a/testing/marionette/harness/marionette_harness/www/windowHandles.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Marionette New Tab Link - - - New Tab - New blank Tab - - New Window - - \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/www/xhtmlTest.html b/testing/marionette/harness/marionette_harness/www/xhtmlTest.html deleted file mode 100644 index 146def33ad..0000000000 --- a/testing/marionette/harness/marionette_harness/www/xhtmlTest.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - 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 deleted file mode 100644 index 75ab9ce92b..0000000000 --- a/testing/marionette/harness/requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -browsermob-proxy >= 0.6.0 -manifestparser >= 1.1 -marionette-driver >= 2.2.0 -mozcrash >= 0.5 -mozdevice >= 0.44 -mozinfo >= 0.8 -mozlog >= 3.0 -moznetwork >= 0.21 -mozprocess >= 0.9 -mozprofile >= 0.7 -mozrunner >= 6.13 -moztest >= 0.8 -mozversion >= 1.1 -wptserve >= 1.3.0 diff --git a/testing/marionette/harness/setup.py b/testing/marionette/harness/setup.py deleted file mode 100644 index d28a970c1e..0000000000 --- a/testing/marionette/harness/setup.py +++ /dev/null @@ -1,59 +0,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='tools-marionette@lists.mozilla.org', - url='https://wiki.mozilla.org/Auto-tools/Projects/Marionette', - license='Mozilla Public License 2.0 (MPL 2.0)', - packages=find_packages(), - package_data={ - 'marionette_harness': [ - 'runner/test.cert', - 'runner/test.key' - ], - }, - # 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/interaction.js b/testing/marionette/interaction.js deleted file mode 100644 index 2392485d73..0000000000 --- a/testing/marionette/interaction.js +++ /dev/null @@ -1,505 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {utils: Cu} = Components; - -Cu.import("chrome://marionette/content/accessibility.js"); -Cu.import("chrome://marionette/content/atom.js"); -Cu.import("chrome://marionette/content/error.js"); -Cu.import("chrome://marionette/content/element.js"); -Cu.import("chrome://marionette/content/event.js"); - -Cu.importGlobalProperties(["File"]); - -this.EXPORTED_SYMBOLS = ["interaction"]; - -/** - * XUL elements that support disabled attribute. - */ -const DISABLED_ATTRIBUTE_SUPPORTED_XUL = new Set([ - "ARROWSCROLLBOX", - "BUTTON", - "CHECKBOX", - "COLORPICKER", - "COMMAND", - "DATEPICKER", - "DESCRIPTION", - "KEY", - "KEYSET", - "LABEL", - "LISTBOX", - "LISTCELL", - "LISTHEAD", - "LISTHEADER", - "LISTITEM", - "MENU", - "MENUITEM", - "MENULIST", - "MENUSEPARATOR", - "PREFERENCE", - "RADIO", - "RADIOGROUP", - "RICHLISTBOX", - "RICHLISTITEM", - "SCALE", - "TAB", - "TABS", - "TEXTBOX", - "TIMEPICKER", - "TOOLBARBUTTON", - "TREE", -]); - -/** - * XUL elements that support checked property. - */ -const CHECKED_PROPERTY_SUPPORTED_XUL = new Set([ - "BUTTON", - "CHECKBOX", - "LISTITEM", - "TOOLBARBUTTON", -]); - -/** - * XUL elements that support selected property. - */ -const SELECTED_PROPERTY_SUPPORTED_XUL = new Set([ - "LISTITEM", - "MENU", - "MENUITEM", - "MENUSEPARATOR", - "RADIO", - "RICHLISTITEM", - "TAB", -]); - -/** - * Common form controls that user can change the value property interactively. - */ -const COMMON_FORM_CONTROLS = new Set([ - "input", - "textarea", - "select", -]); - -/** - * Input elements that do not fire "input" and "change" events when value - * property changes. - */ -const INPUT_TYPES_NO_EVENT = new Set([ - "checkbox", - "radio", - "file", - "hidden", - "image", - "reset", - "button", - "submit", -]); - -this.interaction = {}; - -/** - * Interact with an element by clicking it. - * - * The element is scrolled into view before visibility- or interactability - * checks are performed. - * - * Selenium-style visibility checks will be performed if |specCompat| - * is false (default). Otherwise pointer-interactability checks will be - * performed. If either of these fail an - * {@code ElementNotInteractableError} is thrown. - * - * If |strict| is enabled (defaults to disabled), further accessibility - * checks will be performed, and these may result in an - * {@code ElementNotAccessibleError} being returned. - * - * When |el| is not enabled, an {@code InvalidElementStateError} - * is returned. - * - * @param {DOMElement|XULElement} el - * Element to click. - * @param {boolean=} strict - * Enforce strict accessibility tests. - * @param {boolean=} specCompat - * Use WebDriver specification compatible interactability definition. - * - * @throws {ElementNotInteractableError} - * If either Selenium-style visibility check or - * pointer-interactability check fails. - * @throws {ElementClickInterceptedError} - * If |el| is obscured by another element and a click would not hit, - * in |specCompat| mode. - * @throws {ElementNotAccessibleError} - * If |strict| is true and element is not accessible. - * @throws {InvalidElementStateError} - * If |el| is not enabled. - */ -interaction.clickElement = function* (el, strict = false, specCompat = false) { - const a11y = accessibility.get(strict); - if (specCompat) { - yield webdriverClickElement(el, a11y); - } else { - yield seleniumClickElement(el, a11y); - } -}; - -function* webdriverClickElement (el, a11y) { - const win = getWindow(el); - const doc = win.document; - - // step 3 - if (el.localName == "input" && el.type == "file") { - throw new InvalidArgumentError( - "Cannot click elements"); - } - - let containerEl = element.getContainer(el); - - // step 4 - if (!element.isInView(containerEl)) { - element.scrollIntoView(containerEl); - } - - // step 5 - // TODO(ato): wait for containerEl to be in view - - // step 6 - // if we cannot bring the container element into the viewport - // there is no point in checking if it is pointer-interactable - if (!element.isInView(containerEl)) { - throw new ElementNotInteractableError( - error.pprint`Element ${el} could not be scrolled into view`); - } - - // step 7 - let rects = containerEl.getClientRects(); - let clickPoint = element.getInViewCentrePoint(rects[0], win); - - if (!element.isPointerInteractable(containerEl)) { - throw new ElementClickInterceptedError(containerEl, clickPoint); - } - - yield a11y.getAccessible(el, true).then(acc => { - a11y.assertVisible(acc, el, true); - a11y.assertEnabled(acc, el, true); - a11y.assertActionable(acc, el); - }); - - // step 8 - - // chrome elements - if (element.isXULElement(el)) { - if (el.localName == "option") { - interaction.selectOption(el); - } else { - el.click(); - } - - // content elements - } else { - if (el.localName == "option") { - interaction.selectOption(el); - } else { - event.synthesizeMouseAtPoint(clickPoint.x, clickPoint.y, {}, win); - } - } - - // step 9 - yield interaction.flushEventLoop(win); - - // step 10 - // TODO(ato): if the click causes navigation, - // run post-navigation checks -} - -function* seleniumClickElement (el, a11y) { - let win = getWindow(el); - - let visibilityCheckEl = el; - if (el.localName == "option") { - visibilityCheckEl = element.getContainer(el); - } - - if (!element.isVisible(visibilityCheckEl)) { - throw new ElementNotInteractableError(); - } - - if (!atom.isElementEnabled(el)) { - throw new InvalidElementStateError("Element is not enabled"); - } - - yield a11y.getAccessible(el, true).then(acc => { - a11y.assertVisible(acc, el, true); - a11y.assertEnabled(acc, el, true); - a11y.assertActionable(acc, el); - }); - - // chrome elements - if (element.isXULElement(el)) { - if (el.localName == "option") { - interaction.selectOption(el); - } else { - el.click(); - } - - // content elements - } else { - if (el.localName == "option") { - interaction.selectOption(el); - } else { - let rects = el.getClientRects(); - let centre = element.getInViewCentrePoint(rects[0], win); - let opts = {}; - event.synthesizeMouseAtPoint(centre.x, centre.y, opts, win); - } - } -}; - -/** - * Select