From 1797c146f16ddc1e0249b8bb60284303bd435825 Mon Sep 17 00:00:00 2001 From: Ivan De Marino Date: Tue, 4 Feb 2014 23:24:13 +0000 Subject: [PATCH] Adding "test/ghostdriver-test" to run in Travis CI Related to issue #11880 --- .gitignore | 2 + .travis.yml | 4 +- src/ghostdriver/lastupdate | 11 +- test-ghostdriver.sh | 13 + test/ghostdriver-test/config.ini | 11 + ...kTest_testClicksASurroundingStrongTag.html | 11 + .../fixtures/common/Page.aspx | 17 + .../fixtures/common/Page.aspx.cs | 22 + test/ghostdriver-test/fixtures/common/README | 1 + .../fixtures/common/Redirect.aspx | 11 + .../fixtures/common/Redirect.aspx.cs | 9 + .../fixtures/common/Settings.StyleCop | 759 + .../fixtures/common/Web.Config | 59 + .../fixtures/common/actualXhtmlPage.xhtml | 14 + .../fixtures/common/ajaxy_page.html | 81 + .../fixtures/common/alerts.html | 85 + .../fixtures/common/animals/.gitignore | 0 .../fixtures/common/banner.gif | Bin 0 -> 2109 bytes .../fixtures/common/beach.jpg | Bin 0 -> 14085 bytes .../fixtures/common/blank.html | 1 + .../fixtures/common/bodyTypingTest.html | 41 + .../fixtures/common/booleanAttributes.html | 19 + .../fixtures/common/child/childPage.html | 8 + .../child/grandchild/grandchildPage.html | 8 + .../fixtures/common/clickEventPage.html | 26 + .../fixtures/common/click_frames.html | 10 + .../fixtures/common/click_jacker.html | 38 + .../fixtures/common/click_out_of_bounds.html | 23 + .../common/click_out_of_bounds_overflow.html | 85 + .../fixtures/common/click_rtl.html | 19 + .../fixtures/common/click_source.html | 18 + .../common/click_tests/google_map.html | 15 + .../common/click_tests/google_map.png | Bin 0 -> 26209 bytes .../click_tests/html5_submit_buttons.html | 15 + .../common/click_tests/issue5237.html | 9 + .../common/click_tests/issue5237_frame.html | 1 + .../common/click_tests/issue5237_target.html | 10 + .../common/click_tests/link_that_wraps.html | 11 + .../common/click_tests/mapped_page1.html | 9 + .../common/click_tests/mapped_page2.html | 9 + .../common/click_tests/mapped_page3.html | 9 + .../common/click_tests/span_that_wraps.html | 11 + .../common/click_tests/submitted_page.html | 9 + .../fixtures/common/click_too_big.html | 10 + .../common/click_too_big_in_frame.html | 11 + .../fixtures/common/clicks.html | 35 + .../fixtures/common/closeable_window.html | 8 + .../fixtures/common/cn-test.html | 156 + .../fixtures/common/colorPage.html | 20 + .../fixtures/common/cookies.html | 30 + .../coordinates_tests/element_in_frame.html | 9 + .../element_in_nested_frame.html | 9 + .../page_with_element_out_of_view.html | 11 + .../page_with_empty_element.html | 10 + .../page_with_fixed_element.html | 12 + .../page_with_hidden_element.html | 10 + .../page_with_invisible_element.html | 10 + .../page_with_transparent_element.html | 10 + .../common/coordinates_tests/simple_page.html | 10 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 0 -> 125 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 0 -> 3762 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 0 -> 129 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_228ef1_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ef8c08_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes .../ui-lightness/jquery-ui-1.8.10.custom.css | 573 + .../fixtures/common/cssTransform.html | 61 + .../fixtures/common/cssTransform2.html | 20 + .../common/document_write_in_onload.html | 13 + .../common/dragAndDropInsideScrolledDiv.html | 67 + .../fixtures/common/dragAndDropTest.html | 102 + .../fixtures/common/dragDropOverflow.html | 104 + .../fixtures/common/draggableLists.html | 67 + .../fixtures/common/droppableItems.html | 65 + .../fixtures/common/dynamic.html | 39 + .../common/dynamicallyModifiedPage.html | 42 + .../fixtures/common/errors.html | 15 + .../fixtures/common/fixedFooterNoScroll.html | 13 + .../common/fixedFooterNoScrollQuirksMode.html | 12 + .../fixtures/common/formPage.html | 173 + .../fixtures/common/formSelectionPage.html | 46 + .../common/form_handling_js_submit.html | 30 + .../fixtures/common/framePage3.html | 7 + .../fixtures/common/frameScrollChild.html | 26 + .../fixtures/common/frameScrollPage.html | 14 + .../fixtures/common/frameScrollParent.html | 11 + .../common/frame_switching_tests/bug4876.html | 9 + .../frame_switching_tests/bug4876_iframe.html | 9 + .../frame_switching_tests/deletingFrame.html | 29 + .../deletingFrame_iframe.html | 8 + .../deletingFrame_iframe2.html | 7 + .../fixtures/common/frameset.html | 14 + .../fixtures/common/framesetPage2.html | 7 + .../fixtures/common/framesetPage3.html | 4 + .../fixtures/common/galaxy/.gitignore | 0 .../fixtures/common/globalscope.html | 15 + .../fixtures/common/hidden.html | 5 + .../fixtures/common/html5/blue.jpg | Bin 0 -> 92 bytes .../fixtures/common/html5/database.js | 84 + .../fixtures/common/html5/geolocation.js | 18 + .../fixtures/common/html5/green.jpg | Bin 0 -> 92 bytes .../fixtures/common/html5/offline.html | 1 + .../fixtures/common/html5/red.jpg | Bin 0 -> 92 bytes .../fixtures/common/html5/status.html | 1 + .../fixtures/common/html5/test.appcache | 11 + .../fixtures/common/html5/yellow.jpg | Bin 0 -> 92 bytes .../fixtures/common/html5Page.html | 32 + .../ghostdriver-test/fixtures/common/icon.gif | Bin 0 -> 127 bytes .../fixtures/common/iframeAtBottom.html | 15 + .../fixtures/common/iframeWithAlert.html | 1 + .../fixtures/common/iframeWithIframe.html | 1 + .../fixtures/common/iframes.html | 11 + .../common/javascriptEnhancedForm.html | 30 + .../fixtures/common/javascriptPage.html | 275 + .../fixtures/common/jquery-1.3.2.js | 4376 ++ .../fixtures/common/js/jquery-1.4.4.min.js | 167 + .../common/js/jquery-ui-1.8.10.custom.min.js | 782 + .../common/key_tests/remove_on_keypress.html | 36 + .../fixtures/common/keyboard_shortcut.html | 36 + .../fixtures/common/linked_image.html | 16 + .../boolean_attribute_selected.html | 13 + .../boolean_attribute_selected_html4.html | 13 + .../fixtures/common/longContentPage.html | 55 + .../fixtures/common/macbeth.html | 5255 +++ test/ghostdriver-test/fixtures/common/map.png | Bin 0 -> 26209 bytes .../fixtures/common/map_visibility.html | 8 + .../fixtures/common/markerTransparent.png | Bin 0 -> 260 bytes .../fixtures/common/messages.html | 15 + .../fixtures/common/meta-redirect.html | 11 + .../fixtures/common/missedJsReference.html | 11 + .../common/modal_dialogs/modal_1.html | 21 + .../common/modal_dialogs/modal_2.html | 21 + .../common/modal_dialogs/modal_3.html | 15 + .../common/modal_dialogs/modalindex.html | 21 + .../fixtures/common/mouseOver.html | 17 + .../fixtures/common/mousePositionTracker.html | 33 + .../fixtures/common/nestedElements.html | 155 + .../fixtures/common/overflow-body.html | 15 + .../common/overflow/x_auto_y_auto.html | 30 + .../common/overflow/x_auto_y_hidden.html | 30 + .../common/overflow/x_auto_y_scroll.html | 30 + .../common/overflow/x_hidden_y_auto.html | 30 + .../common/overflow/x_hidden_y_hidden.html | 30 + .../common/overflow/x_hidden_y_scroll.html | 30 + .../common/overflow/x_scroll_y_auto.html | 30 + .../common/overflow/x_scroll_y_hidden.html | 30 + .../common/overflow/x_scroll_y_scroll.html | 30 + .../common/pageWithOnBeforeUnloadMessage.html | 20 + .../fixtures/common/pageWithOnLoad.html | 6 + .../fixtures/common/pageWithOnUnload.html | 6 + .../fixtures/common/plain.txt | 1 + .../fixtures/common/proxy/page1.html | 20 + .../fixtures/common/proxy/page2.html | 24 + .../fixtures/common/proxy/page3.html | 5 + .../fixtures/common/readOnlyPage.html | 22 + .../fixtures/common/rectangles.html | 40 + .../fixtures/common/resultPage.html | 25 + .../fixtures/common/rich_text.html | 160 + .../common/safari/frames_benchmark.html | 31 + .../fixtures/common/screen/screen.css | 19 + .../fixtures/common/screen/screen.html | 72 + .../fixtures/common/screen/screen.js | 7 + .../fixtures/common/screen/screen_frame1.html | 72 + .../fixtures/common/screen/screen_frame2.html | 72 + .../fixtures/common/screen/screen_frames.html | 11 + .../common/screen/screen_iframes.html | 12 + .../common/screen/screen_too_long.html | 68 + .../fixtures/common/screen/screen_x_long.html | 72 + .../common/screen/screen_x_too_long.html | 72 + .../fixtures/common/screen/screen_y_long.html | 72 + .../common/screen/screen_y_too_long.html | 72 + .../fixtures/common/scroll.html | 27 + .../fixtures/common/scroll2.html | 21 + .../fixtures/common/scroll3.html | 8 + .../fixtures/common/scroll4.html | 7 + .../fixtures/common/scroll5.html | 18 + .../frame_with_height_above_200.html | 26 + .../frame_with_height_above_2000.html | 26 + .../frame_with_nested_scrolling_frame.html | 11 + ...th_nested_scrolling_frame_out_of_view.html | 12 + .../frame_with_small_height.html | 10 + .../page_with_double_overflow_auto.html | 19 + .../page_with_frame_out_of_view.html | 12 + .../page_with_nested_scrolling_frames.html | 11 + ...h_nested_scrolling_frames_out_of_view.html | 12 + .../page_with_non_scrolling_frame.html | 11 + .../page_with_scrolling_frame.html | 11 + ...page_with_scrolling_frame_out_of_view.html | 12 + .../scrolling_tests/page_with_tall_frame.html | 11 + .../page_with_y_overflow_auto.html | 14 + .../common/scrolling_tests/target_page.html | 9 + .../fixtures/common/selectPage.html | 42 + .../fixtures/common/selectableItems.html | 65 + .../fixtures/common/sessionCookie.html | 21 + .../fixtures/common/sessionCookieDest.html | 34 + .../fixtures/common/simple.xml | 5 + .../fixtures/common/simpleTest.html | 97 + .../fixtures/common/slowLoadingAlert.html | 10 + .../common/slowLoadingResourcePage.html | 12 + .../fixtures/common/slow_loading_iframes.html | 14 + .../fixtures/common/styledPage.html | 28 + .../fixtures/common/svgPiechart.xhtml | 81 + .../fixtures/common/svgTest.svg | 4 + .../fixtures/common/tables.html | 36 + .../fixtures/common/transformable.xml | 11 + .../fixtures/common/transformable.xsl | 37 + .../fixtures/common/underscore.html | 9 + .../fixtures/common/unicode_ltr.html | 8 + .../fixtures/common/upload.html | 45 + .../fixtures/common/userDefinedProperty.html | 8 + .../fixtures/common/veryLargeCanvas.html | 81 + .../fixtures/common/visibility-css.html | 21 + .../fixtures/common/win32frameset.html | 8 + .../page_with_frame.html | 12 + .../window_switching_tests/simple_page.html | 9 + .../fixtures/common/xhtmlFormPage.xhtml | 17 + .../fixtures/common/xhtmlTest.html | 76 + .../fixtures/right_frame/0.html | 38911 ++++++++++++++++ .../fixtures/right_frame/1.html | 51 + .../fixtures/right_frame/outside.html | 414 + .../fixtures/testcase-issue_240/1 | 0 .../fixtures/testcase-issue_240/2 | 0 .../fixtures/testcase-issue_240/3 | 0 .../fixtures/testcase-issue_240/4 | 0 .../fixtures/testcase-issue_240/5 | 0 .../fixtures/testcase-issue_240/6 | 0 .../fixtures/testcase-issue_240/test.html | 97 + .../fixtures/testcase-issue_240/wb.rb | 62 + test/ghostdriver-test/java/build.gradle | 42 + .../java/gradle/gradle-wrapper.jar | Bin 0 -> 50557 bytes .../java/gradle/gradle-wrapper.properties | 6 + test/ghostdriver-test/java/gradlew | 164 + test/ghostdriver-test/java/gradlew.bat | 90 + test/ghostdriver-test/java/settings.gradle | 1 + .../src/test/java/ghostdriver/BaseTest.java | 163 + .../java/ghostdriver/BaseTestWithServer.java | 47 + .../src/test/java/ghostdriver/CookieTest.java | 317 + .../java/ghostdriver/DriverBasicTest.java | 37 + .../java/ghostdriver/ElementFindingTest.java | 261 + .../ghostdriver/ElementJQueryEventsTest.java | 107 + .../java/ghostdriver/ElementMethodsTest.java | 264 + .../java/ghostdriver/ElementQueryingTest.java | 148 + .../test/java/ghostdriver/FileUploadTest.java | 171 + .../java/ghostdriver/FrameSwitchingTest.java | 492 + .../java/ghostdriver/GoogleSearchTest.java | 55 + .../java/ghostdriver/IsolatedSessionTest.java | 55 + .../src/test/java/ghostdriver/LogTest.java | 90 + .../java/ghostdriver/MouseCommandsTest.java | 132 + .../test/java/ghostdriver/NavigationTest.java | 90 + .../ghostdriver/PhantomJSCommandTest.java | 49 + .../java/ghostdriver/ScriptExecutionTest.java | 135 + .../java/ghostdriver/SessionBasicTest.java | 59 + .../java/ghostdriver/TimeoutSettingTest.java | 43 + .../java/ghostdriver/WindowHandlesTest.java | 103 + .../WindowSizingAndPositioningTest.java | 78 + .../java/ghostdriver/WindowSwitchingTest.java | 220 + .../server/CallbackHttpServer.java | 79 + .../ghostdriver/server/CallbackServlet.java | 58 + .../server/EmptyPageHttpRequestCallback.java | 40 + .../server/GetFixtureHttpRequestCallback.java | 61 + .../server/HttpRequestCallback.java | 36 + 269 files changed, 60607 insertions(+), 5 deletions(-) create mode 100755 test-ghostdriver.sh create mode 100644 test/ghostdriver-test/config.ini create mode 100644 test/ghostdriver-test/fixtures/common/ClickTest_testClicksASurroundingStrongTag.html create mode 100644 test/ghostdriver-test/fixtures/common/Page.aspx create mode 100644 test/ghostdriver-test/fixtures/common/Page.aspx.cs create mode 100644 test/ghostdriver-test/fixtures/common/README create mode 100644 test/ghostdriver-test/fixtures/common/Redirect.aspx create mode 100644 test/ghostdriver-test/fixtures/common/Redirect.aspx.cs create mode 100644 test/ghostdriver-test/fixtures/common/Settings.StyleCop create mode 100644 test/ghostdriver-test/fixtures/common/Web.Config create mode 100644 test/ghostdriver-test/fixtures/common/actualXhtmlPage.xhtml create mode 100644 test/ghostdriver-test/fixtures/common/ajaxy_page.html create mode 100644 test/ghostdriver-test/fixtures/common/alerts.html create mode 100644 test/ghostdriver-test/fixtures/common/animals/.gitignore create mode 100644 test/ghostdriver-test/fixtures/common/banner.gif create mode 100644 test/ghostdriver-test/fixtures/common/beach.jpg create mode 100644 test/ghostdriver-test/fixtures/common/blank.html create mode 100644 test/ghostdriver-test/fixtures/common/bodyTypingTest.html create mode 100644 test/ghostdriver-test/fixtures/common/booleanAttributes.html create mode 100644 test/ghostdriver-test/fixtures/common/child/childPage.html create mode 100644 test/ghostdriver-test/fixtures/common/child/grandchild/grandchildPage.html create mode 100644 test/ghostdriver-test/fixtures/common/clickEventPage.html create mode 100644 test/ghostdriver-test/fixtures/common/click_frames.html create mode 100644 test/ghostdriver-test/fixtures/common/click_jacker.html create mode 100644 test/ghostdriver-test/fixtures/common/click_out_of_bounds.html create mode 100644 test/ghostdriver-test/fixtures/common/click_out_of_bounds_overflow.html create mode 100644 test/ghostdriver-test/fixtures/common/click_rtl.html create mode 100644 test/ghostdriver-test/fixtures/common/click_source.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/google_map.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/google_map.png create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/html5_submit_buttons.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/issue5237.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/issue5237_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/issue5237_target.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/link_that_wraps.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/mapped_page1.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/mapped_page2.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/mapped_page3.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/span_that_wraps.html create mode 100644 test/ghostdriver-test/fixtures/common/click_tests/submitted_page.html create mode 100644 test/ghostdriver-test/fixtures/common/click_too_big.html create mode 100644 test/ghostdriver-test/fixtures/common/click_too_big_in_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/clicks.html create mode 100644 test/ghostdriver-test/fixtures/common/closeable_window.html create mode 100644 test/ghostdriver-test/fixtures/common/cn-test.html create mode 100644 test/ghostdriver-test/fixtures/common/colorPage.html create mode 100644 test/ghostdriver-test/fixtures/common/cookies.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_nested_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_element_out_of_view.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_empty_element.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_fixed_element.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_hidden_element.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_invisible_element.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_transparent_element.html create mode 100644 test/ghostdriver-test/fixtures/common/coordinates_tests/simple_page.html create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_222222_256x240.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_228ef1_256x240.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ef8c08_256x240.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ffd27a_256x240.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ffffff_256x240.png create mode 100644 test/ghostdriver-test/fixtures/common/css/ui-lightness/jquery-ui-1.8.10.custom.css create mode 100644 test/ghostdriver-test/fixtures/common/cssTransform.html create mode 100644 test/ghostdriver-test/fixtures/common/cssTransform2.html create mode 100644 test/ghostdriver-test/fixtures/common/document_write_in_onload.html create mode 100644 test/ghostdriver-test/fixtures/common/dragAndDropInsideScrolledDiv.html create mode 100644 test/ghostdriver-test/fixtures/common/dragAndDropTest.html create mode 100644 test/ghostdriver-test/fixtures/common/dragDropOverflow.html create mode 100644 test/ghostdriver-test/fixtures/common/draggableLists.html create mode 100644 test/ghostdriver-test/fixtures/common/droppableItems.html create mode 100644 test/ghostdriver-test/fixtures/common/dynamic.html create mode 100644 test/ghostdriver-test/fixtures/common/dynamicallyModifiedPage.html create mode 100644 test/ghostdriver-test/fixtures/common/errors.html create mode 100644 test/ghostdriver-test/fixtures/common/fixedFooterNoScroll.html create mode 100644 test/ghostdriver-test/fixtures/common/fixedFooterNoScrollQuirksMode.html create mode 100644 test/ghostdriver-test/fixtures/common/formPage.html create mode 100644 test/ghostdriver-test/fixtures/common/formSelectionPage.html create mode 100644 test/ghostdriver-test/fixtures/common/form_handling_js_submit.html create mode 100644 test/ghostdriver-test/fixtures/common/framePage3.html create mode 100644 test/ghostdriver-test/fixtures/common/frameScrollChild.html create mode 100644 test/ghostdriver-test/fixtures/common/frameScrollPage.html create mode 100644 test/ghostdriver-test/fixtures/common/frameScrollParent.html create mode 100644 test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876.html create mode 100644 test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876_iframe.html create mode 100644 test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame.html create mode 100644 test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe.html create mode 100644 test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe2.html create mode 100644 test/ghostdriver-test/fixtures/common/frameset.html create mode 100644 test/ghostdriver-test/fixtures/common/framesetPage2.html create mode 100644 test/ghostdriver-test/fixtures/common/framesetPage3.html create mode 100644 test/ghostdriver-test/fixtures/common/galaxy/.gitignore create mode 100644 test/ghostdriver-test/fixtures/common/globalscope.html create mode 100644 test/ghostdriver-test/fixtures/common/hidden.html create mode 100644 test/ghostdriver-test/fixtures/common/html5/blue.jpg create mode 100644 test/ghostdriver-test/fixtures/common/html5/database.js create mode 100644 test/ghostdriver-test/fixtures/common/html5/geolocation.js create mode 100644 test/ghostdriver-test/fixtures/common/html5/green.jpg create mode 100644 test/ghostdriver-test/fixtures/common/html5/offline.html create mode 100644 test/ghostdriver-test/fixtures/common/html5/red.jpg create mode 100644 test/ghostdriver-test/fixtures/common/html5/status.html create mode 100644 test/ghostdriver-test/fixtures/common/html5/test.appcache create mode 100644 test/ghostdriver-test/fixtures/common/html5/yellow.jpg create mode 100644 test/ghostdriver-test/fixtures/common/html5Page.html create mode 100644 test/ghostdriver-test/fixtures/common/icon.gif create mode 100644 test/ghostdriver-test/fixtures/common/iframeAtBottom.html create mode 100644 test/ghostdriver-test/fixtures/common/iframeWithAlert.html create mode 100644 test/ghostdriver-test/fixtures/common/iframeWithIframe.html create mode 100644 test/ghostdriver-test/fixtures/common/iframes.html create mode 100644 test/ghostdriver-test/fixtures/common/javascriptEnhancedForm.html create mode 100644 test/ghostdriver-test/fixtures/common/javascriptPage.html create mode 100644 test/ghostdriver-test/fixtures/common/jquery-1.3.2.js create mode 100644 test/ghostdriver-test/fixtures/common/js/jquery-1.4.4.min.js create mode 100644 test/ghostdriver-test/fixtures/common/js/jquery-ui-1.8.10.custom.min.js create mode 100644 test/ghostdriver-test/fixtures/common/key_tests/remove_on_keypress.html create mode 100644 test/ghostdriver-test/fixtures/common/keyboard_shortcut.html create mode 100644 test/ghostdriver-test/fixtures/common/linked_image.html create mode 100644 test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected.html create mode 100644 test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected_html4.html create mode 100644 test/ghostdriver-test/fixtures/common/longContentPage.html create mode 100644 test/ghostdriver-test/fixtures/common/macbeth.html create mode 100644 test/ghostdriver-test/fixtures/common/map.png create mode 100644 test/ghostdriver-test/fixtures/common/map_visibility.html create mode 100644 test/ghostdriver-test/fixtures/common/markerTransparent.png create mode 100644 test/ghostdriver-test/fixtures/common/messages.html create mode 100644 test/ghostdriver-test/fixtures/common/meta-redirect.html create mode 100644 test/ghostdriver-test/fixtures/common/missedJsReference.html create mode 100644 test/ghostdriver-test/fixtures/common/modal_dialogs/modal_1.html create mode 100644 test/ghostdriver-test/fixtures/common/modal_dialogs/modal_2.html create mode 100644 test/ghostdriver-test/fixtures/common/modal_dialogs/modal_3.html create mode 100644 test/ghostdriver-test/fixtures/common/modal_dialogs/modalindex.html create mode 100644 test/ghostdriver-test/fixtures/common/mouseOver.html create mode 100644 test/ghostdriver-test/fixtures/common/mousePositionTracker.html create mode 100644 test/ghostdriver-test/fixtures/common/nestedElements.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow-body.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_auto_y_auto.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_auto_y_hidden.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_auto_y_scroll.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_auto.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_hidden.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_scroll.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_auto.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_hidden.html create mode 100644 test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_scroll.html create mode 100644 test/ghostdriver-test/fixtures/common/pageWithOnBeforeUnloadMessage.html create mode 100644 test/ghostdriver-test/fixtures/common/pageWithOnLoad.html create mode 100644 test/ghostdriver-test/fixtures/common/pageWithOnUnload.html create mode 100644 test/ghostdriver-test/fixtures/common/plain.txt create mode 100644 test/ghostdriver-test/fixtures/common/proxy/page1.html create mode 100644 test/ghostdriver-test/fixtures/common/proxy/page2.html create mode 100644 test/ghostdriver-test/fixtures/common/proxy/page3.html create mode 100644 test/ghostdriver-test/fixtures/common/readOnlyPage.html create mode 100644 test/ghostdriver-test/fixtures/common/rectangles.html create mode 100644 test/ghostdriver-test/fixtures/common/resultPage.html create mode 100644 test/ghostdriver-test/fixtures/common/rich_text.html create mode 100644 test/ghostdriver-test/fixtures/common/safari/frames_benchmark.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen.css create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen.js create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_frame1.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_frame2.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_frames.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_iframes.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_too_long.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_x_long.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_x_too_long.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_y_long.html create mode 100644 test/ghostdriver-test/fixtures/common/screen/screen_y_too_long.html create mode 100644 test/ghostdriver-test/fixtures/common/scroll.html create mode 100644 test/ghostdriver-test/fixtures/common/scroll2.html create mode 100644 test/ghostdriver-test/fixtures/common/scroll3.html create mode 100644 test/ghostdriver-test/fixtures/common/scroll4.html create mode 100644 test/ghostdriver-test/fixtures/common/scroll5.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_200.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_2000.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_small_height.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_double_overflow_auto.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_frame_out_of_view.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_non_scrolling_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame_out_of_view.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_tall_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_y_overflow_auto.html create mode 100644 test/ghostdriver-test/fixtures/common/scrolling_tests/target_page.html create mode 100644 test/ghostdriver-test/fixtures/common/selectPage.html create mode 100644 test/ghostdriver-test/fixtures/common/selectableItems.html create mode 100644 test/ghostdriver-test/fixtures/common/sessionCookie.html create mode 100644 test/ghostdriver-test/fixtures/common/sessionCookieDest.html create mode 100644 test/ghostdriver-test/fixtures/common/simple.xml create mode 100644 test/ghostdriver-test/fixtures/common/simpleTest.html create mode 100644 test/ghostdriver-test/fixtures/common/slowLoadingAlert.html create mode 100644 test/ghostdriver-test/fixtures/common/slowLoadingResourcePage.html create mode 100644 test/ghostdriver-test/fixtures/common/slow_loading_iframes.html create mode 100644 test/ghostdriver-test/fixtures/common/styledPage.html create mode 100644 test/ghostdriver-test/fixtures/common/svgPiechart.xhtml create mode 100644 test/ghostdriver-test/fixtures/common/svgTest.svg create mode 100644 test/ghostdriver-test/fixtures/common/tables.html create mode 100644 test/ghostdriver-test/fixtures/common/transformable.xml create mode 100644 test/ghostdriver-test/fixtures/common/transformable.xsl create mode 100644 test/ghostdriver-test/fixtures/common/underscore.html create mode 100644 test/ghostdriver-test/fixtures/common/unicode_ltr.html create mode 100644 test/ghostdriver-test/fixtures/common/upload.html create mode 100644 test/ghostdriver-test/fixtures/common/userDefinedProperty.html create mode 100644 test/ghostdriver-test/fixtures/common/veryLargeCanvas.html create mode 100644 test/ghostdriver-test/fixtures/common/visibility-css.html create mode 100644 test/ghostdriver-test/fixtures/common/win32frameset.html create mode 100644 test/ghostdriver-test/fixtures/common/window_switching_tests/page_with_frame.html create mode 100644 test/ghostdriver-test/fixtures/common/window_switching_tests/simple_page.html create mode 100644 test/ghostdriver-test/fixtures/common/xhtmlFormPage.xhtml create mode 100644 test/ghostdriver-test/fixtures/common/xhtmlTest.html create mode 100644 test/ghostdriver-test/fixtures/right_frame/0.html create mode 100644 test/ghostdriver-test/fixtures/right_frame/1.html create mode 100644 test/ghostdriver-test/fixtures/right_frame/outside.html create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/1 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/2 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/3 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/4 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/5 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/6 create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/test.html create mode 100644 test/ghostdriver-test/fixtures/testcase-issue_240/wb.rb create mode 100644 test/ghostdriver-test/java/build.gradle create mode 100644 test/ghostdriver-test/java/gradle/gradle-wrapper.jar create mode 100644 test/ghostdriver-test/java/gradle/gradle-wrapper.properties create mode 100755 test/ghostdriver-test/java/gradlew create mode 100644 test/ghostdriver-test/java/gradlew.bat create mode 100644 test/ghostdriver-test/java/settings.gradle create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTestWithServer.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/CookieTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/DriverBasicTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/ElementFindingTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/ElementJQueryEventsTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/ElementMethodsTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/ElementQueryingTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/FileUploadTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/FrameSwitchingTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/GoogleSearchTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/IsolatedSessionTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/LogTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/MouseCommandsTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/NavigationTest.java create mode 100755 test/ghostdriver-test/java/src/test/java/ghostdriver/PhantomJSCommandTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/ScriptExecutionTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/SessionBasicTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/TimeoutSettingTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/WindowHandlesTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSizingAndPositioningTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSwitchingTest.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackHttpServer.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackServlet.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/server/EmptyPageHttpRequestCallback.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/server/GetFixtureHttpRequestCallback.java create mode 100644 test/ghostdriver-test/java/src/test/java/ghostdriver/server/HttpRequestCallback.java diff --git a/.gitignore b/.gitignore index 64a6dad4..82ee57e0 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,5 @@ tools/dump_syms.app/ [Dd]ebug*/ [Rr]elease/ bin/ +*.class +build/ diff --git a/.travis.yml b/.travis.yml index 749c2680..34b1c199 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,5 +9,7 @@ install: - sudo apt-get -yq install build-essential chrpath libssl-dev libfontconfig1-dev #< Build Dependencies before_script: - chmod +x ./build.sh + - chmod +x ./test-ghostdriver.sh script: - - ./build.sh --confirm --silent + - ./build.sh --confirm --silent #< Build + - ./test-ghostdriver.sh #< Test (GhostDriver / PhantomJSDriver) diff --git a/src/ghostdriver/lastupdate b/src/ghostdriver/lastupdate index e3ba4bbf..f60c9bd9 100644 --- a/src/ghostdriver/lastupdate +++ b/src/ghostdriver/lastupdate @@ -1,7 +1,10 @@ -2014-01-12 21:02:05 +2014-02-04 23:18:11 -commit 24452f72b6daa0a8ba14822172012d781c89fbcb (HEAD, tag: refs/tags/1.1.1, refs/heads/master) +commit c85f27f06cf23d8ef783c6c9afe54b2975f59249 (HEAD, refs/heads/master) Author: Ivan De Marino -Date: Sun Jan 12 20:37:01 2014 +0000 +Date: Tue Feb 4 22:27:45 2014 +0000 - Changing only the Driver (no need for the Java Bindings) to 1.1.1 + Moving "test fixtures" into "fixtures" directory. + + Also, removing Python tests: never used and extremely limited. + The Selenium PhantomJSDriver maintainer for Python has its own tests. diff --git a/test-ghostdriver.sh b/test-ghostdriver.sh new file mode 100755 index 00000000..cc6dd7d8 --- /dev/null +++ b/test-ghostdriver.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Go to GhostDriver (Java) Tests +pushd ./test/ghostdriver-test/java + +# Ensure Gradle Wrapper is executable +chmod +x ./gradlew + +# Run tests +./gradlew test + +# Return to starting directory +popd diff --git a/test/ghostdriver-test/config.ini b/test/ghostdriver-test/config.ini new file mode 100644 index 00000000..dbfdb2fb --- /dev/null +++ b/test/ghostdriver-test/config.ini @@ -0,0 +1,11 @@ +# What WebDriver to use for the tests +driver=phantomjs +#driver=firefox +#driver=chrome +#driver=http://localhost:8910 +#driver=http://localhost:4444/wd/hub + +# PhantomJS specific config (change according to your installation) +phantomjs_exec_path=../../../bin/phantomjs +#phantomjs_driver_path=../../src/main.js +#phantomjs_driver_loglevel=DEBUG diff --git a/test/ghostdriver-test/fixtures/common/ClickTest_testClicksASurroundingStrongTag.html b/test/ghostdriver-test/fixtures/common/ClickTest_testClicksASurroundingStrongTag.html new file mode 100644 index 00000000..3d117df3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/ClickTest_testClicksASurroundingStrongTag.html @@ -0,0 +1,11 @@ + + + + ClickTest_testClicksASurroundingStrongTag + + +
+ Click +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/Page.aspx b/test/ghostdriver-test/fixtures/common/Page.aspx new file mode 100644 index 00000000..8e3a0d4d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Page.aspx @@ -0,0 +1,17 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Page.aspx.cs" Inherits="Page" %> + + + + + + Untitled Page + + + top +
+
+ +
+
+ + diff --git a/test/ghostdriver-test/fixtures/common/Page.aspx.cs b/test/ghostdriver-test/fixtures/common/Page.aspx.cs new file mode 100644 index 00000000..1a8f7fe3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Page.aspx.cs @@ -0,0 +1,22 @@ +using System; +using System.Threading; + +public partial class Page : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + Response.ContentType = "text/html"; + + int lastIndex = Request.PathInfo.LastIndexOf("/"); + string pageNumber = (lastIndex == -1 ? "Unknown" : Request.PathInfo.Substring(lastIndex + 1)); + if (!string.IsNullOrEmpty(Request.QueryString["pageNumber"])) + { + pageNumber = Request.QueryString["pageNumber"]; + } + Response.Output.Write("Page" + pageNumber + ""); + Response.Output.Write("Page number "); + Response.Output.Write(pageNumber); + //Response.Output.Write("")' + Response.Output.Write(""); + } +} diff --git a/test/ghostdriver-test/fixtures/common/README b/test/ghostdriver-test/fixtures/common/README new file mode 100644 index 00000000..c68ee4c5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/README @@ -0,0 +1 @@ +Those are cut&pasted from Selenium test fixtures diff --git a/test/ghostdriver-test/fixtures/common/Redirect.aspx b/test/ghostdriver-test/fixtures/common/Redirect.aspx new file mode 100644 index 00000000..52d2e678 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Redirect.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Redirect.aspx.cs" Inherits="Redirect" %> + + + + + + Untitled Page + + + + diff --git a/test/ghostdriver-test/fixtures/common/Redirect.aspx.cs b/test/ghostdriver-test/fixtures/common/Redirect.aspx.cs new file mode 100644 index 00000000..9e0650bf --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Redirect.aspx.cs @@ -0,0 +1,9 @@ +using System; + +public partial class Redirect : Page +{ + protected new void Page_Load(object sender, EventArgs e) + { + Response.Redirect("resultPage.html"); + } +} diff --git a/test/ghostdriver-test/fixtures/common/Settings.StyleCop b/test/ghostdriver-test/fixtures/common/Settings.StyleCop new file mode 100644 index 00000000..fc955f81 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Settings.StyleCop @@ -0,0 +1,759 @@ + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/Web.Config b/test/ghostdriver-test/fixtures/common/Web.Config new file mode 100644 index 00000000..68b648f8 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/Web.Config @@ -0,0 +1,59 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/actualXhtmlPage.xhtml b/test/ghostdriver-test/fixtures/common/actualXhtmlPage.xhtml new file mode 100644 index 00000000..a0f54703 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/actualXhtmlPage.xhtml @@ -0,0 +1,14 @@ + + + + + + Title + + + +

+ Foo +

+ + diff --git a/test/ghostdriver-test/fixtures/common/ajaxy_page.html b/test/ghostdriver-test/fixtures/common/ajaxy_page.html new file mode 100644 index 00000000..4b34031d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/ajaxy_page.html @@ -0,0 +1,81 @@ + + + +
+ + +
+ + Red + Green +
+ +
+ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/alerts.html b/test/ghostdriver-test/fixtures/common/alerts.html new file mode 100644 index 00000000..1add0db9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/alerts.html @@ -0,0 +1,85 @@ + + + + + Testing Alerts + + + + + +

Testing Alerts and Stuff

+ +

This tests alerts: click me

+ +

This tests alerts: click me

+ +

Let's make the prompt happen

+ +

Let's make the prompt with default happen

+ +

Let's make TWO prompts happen

+ +

A SLOW alert

+ +

This is a test of a confirm: + test confirm

+ +

This is a test of showModalDialog: test dialog

+ +

This is a test of an alert in an iframe: + +

+ +

This is a test of an alert in a nested iframe: + +

+ +

This is a test of an alert open from onload event handler: open new page

+ +

This is a test of an alert open from onload event handler: open new window

+ +

This is a test of an alert open from onunload event handler: open new page

+ +

This is a test of an alert open from onclose event handler: open new window

+ +

This is a test of an alert open from onclose event handler: open new window

+ +
+
+
+ +

+

+ + diff --git a/test/ghostdriver-test/fixtures/common/animals/.gitignore b/test/ghostdriver-test/fixtures/common/animals/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/common/banner.gif b/test/ghostdriver-test/fixtures/common/banner.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f3435401f878af30930bfb19ee1e340d823e706 GIT binary patch literal 2109 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 diff --git a/test/ghostdriver-test/fixtures/common/bodyTypingTest.html b/test/ghostdriver-test/fixtures/common/bodyTypingTest.html new file mode 100644 index 00000000..f2b1939f --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/bodyTypingTest.html @@ -0,0 +1,41 @@ + + + + Testing Typing into body + + + + +

Type Stuff

+ +
+   +
+ +
+   +
+ + + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/booleanAttributes.html b/test/ghostdriver-test/fixtures/common/booleanAttributes.html new file mode 100644 index 00000000..16fbbe9f --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/booleanAttributes.html @@ -0,0 +1,19 @@ + + + Elements with boolean attributes + + +
+ + + + + +
+ + +
+ +
Unwrappable text
+ + diff --git a/test/ghostdriver-test/fixtures/common/child/childPage.html b/test/ghostdriver-test/fixtures/common/child/childPage.html new file mode 100644 index 00000000..9192b54a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/child/childPage.html @@ -0,0 +1,8 @@ + + + Depth one child page + + +

I'm a page in a child directory

+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/child/grandchild/grandchildPage.html b/test/ghostdriver-test/fixtures/common/child/grandchild/grandchildPage.html new file mode 100644 index 00000000..f52685e0 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/child/grandchild/grandchildPage.html @@ -0,0 +1,8 @@ + + + Depth two child page + + +

I'm a page in a grandchild directory! How cute!

+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/clickEventPage.html b/test/ghostdriver-test/fixtures/common/clickEventPage.html new file mode 100644 index 00000000..8e0355d9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/clickEventPage.html @@ -0,0 +1,26 @@ + + + + Testing click events + + + +
+ Click me to view my coordinates +
+ +
+

 

+
+ + diff --git a/test/ghostdriver-test/fixtures/common/click_frames.html b/test/ghostdriver-test/fixtures/common/click_frames.html new file mode 100644 index 00000000..bd055c7c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_frames.html @@ -0,0 +1,10 @@ + + + click frames + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_jacker.html b/test/ghostdriver-test/fixtures/common/click_jacker.html new file mode 100644 index 00000000..0ff3900e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_jacker.html @@ -0,0 +1,38 @@ + + + + click-jacking + + + +
+
Click jacked!
+
Click Me
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_out_of_bounds.html b/test/ghostdriver-test/fixtures/common/click_out_of_bounds.html new file mode 100644 index 00000000..8a51659b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_out_of_bounds.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+ + + diff --git a/test/ghostdriver-test/fixtures/common/click_out_of_bounds_overflow.html b/test/ghostdriver-test/fixtures/common/click_out_of_bounds_overflow.html new file mode 100644 index 00000000..15ac17f9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_out_of_bounds_overflow.html @@ -0,0 +1,85 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
click me
+
+ diff --git a/test/ghostdriver-test/fixtures/common/click_rtl.html b/test/ghostdriver-test/fixtures/common/click_rtl.html new file mode 100644 index 00000000..e84fffa9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_rtl.html @@ -0,0 +1,19 @@ + + +RTL test + + + +
+ +
Ù…Ùتاح معايير الويب
+ +
פעילות הבינ×ו×
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_source.html b/test/ghostdriver-test/fixtures/common/click_source.html new file mode 100644 index 00000000..22e9319a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_source.html @@ -0,0 +1,18 @@ + + + Click Source + + + I go to a target + + + + + + Click Source + + + I go to a target + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_tests/google_map.html b/test/ghostdriver-test/fixtures/common/click_tests/google_map.html new file mode 100644 index 00000000..eb2e556c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/google_map.html @@ -0,0 +1,15 @@ + + + + Google Image Map + + +

Google Image Map

+ + +area 1 +area 2 +area 3 + + + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/google_map.png b/test/ghostdriver-test/fixtures/common/click_tests/google_map.png new file mode 100644 index 0000000000000000000000000000000000000000..763f5627995f6f178e8ea78e37f32c80b35f5e2b GIT binary patch literal 26209 zcmW(+WmH?;5)HvpG-%NhT#CCC2$bRu#ob!mrMMF)?(SOLiaW)vxI>Xr+}&QjH!Joh zcinT&T{C<3-V?5@D20hef(8HpFlD4AQ~>}48~ATu5D@+ulh{52|9ayft?di|uu}i` zM(`*Sbprq_@MI*!)IFAuJKQsAHC^d_Cptb~UmPw7gzd|W5X(ToM%_q=H@K0G6E}hZ zwnvS(O+U}8W|j}Tt7>Z<0g)VZ)KLH6U>aqpfSfc}fsF7>i(%CduTz1&+d-c-E|MY{ zVObxMf@E&4=T^J9%2VO<$4@u`m@74yLQ5L%QPs=_Jl1+zslu;mD@A4UEaV#sCS9yEo+M~1aNGOxR^)bWw_In|O@gXac`wkLkwJ>7M41bn z1E_~v>poGbi*I&Oi8kzte-!K$EqPw)xURnHE6P)KQ?q| z+smXi0#X482dM&k10g^Fs2d1^0T|H4tdYP)%6ZqDfiSe9M9l(Wt3tlicUVm^pFRqc zIxd9@3(Xhb?0pe^Eep!&{IdHJQGS&k!7&ksSR~K8rnamf+3Lg;QyM<}rpU(1vawM$ z<+*H3t71e+|Ed7S&(6*+BC5da7{VtL}~BuOZhP}EYyDYOQZ?vI*P(1-UASLbJel}om!Dw<;U zM@N`K<`#=%znnkm>KW){XJqJVYg;zz$i#zj0PRhO?m;GWq&tmhX-jnq3_Ojg*hFcy z?ItB78Lyj98{`xe8$WGz{rvohLMPjV94@fWiUc=)_N`vP)`X?zBV?AeAbs;_c=fb& zF+)gW{#0WOR1g3#kQ{`7r0)MtT-ma+K^5(DX~O_}FhrtK%=-1#*e&gbZTho&Ljizo zoiMA5)@zvfUQg22<{VSk9-ZT8;d!)iSF*r3GCZFlVYuSC%s|72@s~Omo{-#p5!M05 z=j5ND(c)>dGIbJi^5erpFA=IC8I-sVbeD0T{qc>)aGWnR3cqMf)STvPUClE2-<$BX zIu)tCC(A)f)w#2;ambT~^FD)vn)A-OzwoE*aos*N3n>)CC{=PmV z5v@V867U8f5eoqMBR~O;75qA^DQ&H-*(D&SX{g!l2Ypv1&pp-*qS~_l+Cq+u;6)u- z)jG+=D}2(AKG(I`p0pbip9&kX`q)9hN*)u3JD;~WI3{+ubD7R_$?4@5H*85?G)JN| z2tViccJFupgQ7CQ)bYiL7>mR#)j_!c@iZ#qas#N_V5N z49B`~ZO2Vl{;0p0Rfa)$GHZ!_Kh3Dq%rK zwWpU}EE7*7!$~~2SKLUWzsQrZ_N}J<(g-^UD?c`rMk+au$gAjYo{Gx0A#QscxP z2%t!%Il%$}!MJ(v&(#SkR{PV_SarL#gAIFA?J3_8J`tBS20nwthhTE@w?zpPA44Xq z=j#$ssJ^?tT#cW1Ji;;y%eYCWt>VA4(6W#Y9>rhslJlFoaOC{*?wp#Nn_F93o0(B# zO}V`H#{cwEMPBquM#eVt>ba`*=XFcFKHiJmWw zoCiVU;s<{DMJ!Hf?EdT?Z@DtUlTpsM)#3(hl`(+O$*%O zobr6vw6zG-wrpxyk8KviZxRl~&`f3%K87m&-o3m(IXMXk2Vy-Yt43`}@RXWEC3ah=}NTA1`l@S8vDL9!X>rxym3eWN~i-BQ?;V{;*-N(5P8R zW-M3e>qVcJh|g|M*OPsTEy;>>qRnC%yY}O?c;;sz3vkQU&DFu9s<9D$RPn5JCNDX? z!i-fjP0Q6)T0NacKEuJuJ0cPi5;C%*laq;EC;In0YO?0_OY(GTOi7-eo(~TXo}Ly> zku2WV^Q%E#t%!smB7p`nXvu3*zYg6;vtI&kSpLJZ9Tq?4b_>}&4CotpkM02!P9W*0 zJce$7Kj2~u5l8BRZGrCg#GT40a@Ja}I?k3jg4D9Stogb)<%s-PL9XaxYHDg|NZQcQ zuvSYiCK8A0A+=PQ0bW4h8n=v+a-9 zyj4<-I>pu1N{3N@8!&a1=nF4n$PgHSY+y2hWxfxJyQiJ&zBb`15QQR*?FY0ajjiSD zh9xF*5_`}6Y*`%mDhCD!rKF_ZC&}V}I`ka!VmP<$-F0fwS{0oVzD+xPj3Ou^19)s2 zeMzlgM^C7CS+=+g{Z2ZuoA%8#%zlxvJNBbU7%Hyzcl*r{1ZpW{swl0OzweJ*Pzs>& zPL%_V1a;%7%X5XltMEzeJ6!C`z*o1oN{Wink&%hAMQU#C?~A5`FVMHd3dg$(vwze_Uw6)p#86x;t0{Eh;jWxhCVGF zi)Q%Jn0zFvhLkH`)%4^@D!msUUQ$jN3G)B^`J<4*i;0N|Uy<6Y1&Y|z+8TMNG5)9f zqinxtSqnETgh&{HoBWs}E5A_3Q>Gg{?NdH?)&eX z=-p3Uaey2RD|+QB%MDd)4l<+t`?OzJqpz1=Uc@MVk%_e2F_Tc~puHSWk2XB~W9=$+ z?BP`_Q>UZCYCiS*9uae^8(6F!^YS7m4t!Q%}5fs6~W^~LAroe z8rPC%h%S0MnX6V|t!2gPnSh9ljEtO|B}sNNi-{54h2YBYb)u%<>*mzZEqZjfGyMO7 ziL_Mng)tLH462Q3yu*$yVbGjC-tZvva6`* zXg7Cv(UNufkh6r^HNoZ{v zb`d{v@^a9W_4~Gp+SV%!O@At>PDERRpFKQ}?x{1GjiZJ1?(CS+B@A2CFWK-$PKrfwnMosCLJbj${wd7=QcqGxAcc=k9U1u`)=0tAZw6S=L6?DVdyd zWFPO^sbzIzBWH4t@8@8s?IM>c>;o&;1;1zi+X&>aHcG>`6$Ts&7mR@*Sfd%Hkd(x3 zJ~2gic6K)Wk&d$a4sT8h!r~Me>d`2y5GKg{ZqOo)u zR8jp@it-~9>>27qXhM`}?=0cgQCiKt%)vX1SB!+>Jtf~B1l0KwJ@UM1RTf*QX! z8x*sxS$vm_r~Nz9{M;a>*1L5q_mtZz8ZIAVDTAo-n(`uyYw>=lG${on@ z#8A{DXfxiTHD;jyfy~xcE^|@J<|b+Gp~=)QOz{3c+3KI^S?R5jv&sAGLia0tLlaqF znF|TY5V-(o00!DpC}Vf9HRd80b<>8asB;KI5o;&A=L~7z<%FmO_?ylAIEypb!y9+6 zUkBherkEN+8(~(6-3rH~?&5hRV;&aR8@^nAk0^_xsN=kaC{gAgH(^;I&kibyN@eRe zJV*f&l);n?n5Biwxz_eh8_l&@;k^qToR=iIS^BTdD&xP!*wMHHdT$ zNZs8)NG<|2Km!2Bz(oFN0DMSb+16H4jRP{$Ct?p$tS)l2m7Js|_dSF*zwn!hnJR&% zX|qEKONlwgpG-*Fw8mc$%p94=@&TzmaUeu=_V8FO`gu@X4K)OZ(kZcl5wv4ledzmW z?e+Nnj~X&p-N+oXHC{XOVHkD0AD`c&PU}s^;@6MqOxBbvtAhdVmJEKkNt(!XP?7=2=lgNj5!zxMVbiU$2km^4o>wbX z*Vosd9AA(9LM-BT>ad_syU~e5YHQO}M4-miXuHR(3lNuodD4TqqKq2e+a`}5c4JUKlKvz48GvwWfVqgie}o~Ifp&?LDQTn6I`U8ps9z`*{MEeo#`}S{*d}qqE z`=7mzvV_LquOm)vwt2KbfGh%4DFBf+K(g8`v^1jZbKc9HVuf2$nXflYML(kLquz zpmYQsSJg3^HM)j)3d^gpfP>L4iH9ZQhwsQiu-M;$Kz9-Rjf;&fK0SknwT=1R3zdK& z1#Du9dIWSFqQ0F>Y_niuB*}*@JyuO-LOzqULE)bV@og9A-p`m*UyWA>BxgQv7uuP2 z|57k@)-6d6LroC>ZNUi+g_Tx@r&q3CTx=G^V2WO88P}3amN5m#j!V-8sUYbDhz}zh z!8*Ntp5-<$e79`%yKY9C*PDdbuu(-&#r zd40XO#!y`2n0L?3PSW0haM3T}7;|`6_@Sl$570)c7gP}s`%v|H$LxX1rSJ2}OirK< z;tB`vLBpydNwLAuq@K$_PuZ}fW(p&IhoW3;|5B3G>q!S5_J?U6Ae_1gu`cIZPkY_W`8y$UOAOtq)n1TC!toD5CVPX&9tSg}W4mA2*oEVH-i$Sv zIhOEG-Kvt;Cu~dZyg7|Il7;l+-3FQF$1UfZOfQSo8B!!Mx&%haxRiagK&V8f^ZfGj zURG1d+)>-}#P~*gM{{B@a&KlrMUXsF019*p?Esrq zC6r$*C9`TNqqq>dfJ(&x5&;qZQNBA$UtbO#PQqLqM`a9qqOgl|I%q|jr5%~+aPWj= zWdewg%TnrOU;~1dMZcZ&el$gtHej(2{bTQE2eM_B^00gH>17gFm(uI}AU*b1(bh=r z;c#%*^nSV8f@+Rf&hIk$HstHEh8f@OfVMsoqkxV0+a;W*IjL0*9dn*Q8{gRaZEd)X zTGE*t4#6L;(o>EFF6GDm<})yv)vu}Ge^LP>joCzMiySuuRr~ICAG>GzUPp!e`pJaH zAF78E2vvqsG9U|JqNeEDKNCO3ytdt?Yl_abQ2@FtHxytJ)@A@>2(A-QUi_$!zbIEv z{g;VjK}@-+%#p~oz4wZ3Jl&$r)^vov6>quSsioS6&z#(LcBc*RiYBw0>wiJ;{g*r) zUT9v1l(xmT~n0Gjdf&m~Hm|@6ziAT+Abh5fGsveMNGuGalG2>L)$Y`JXL zWZk%|>Uxzv@P6W}k2h6^keW-XBa|3K4X$1b0H6gbSFfUNc!zgv7W541DkjTu*6+Mr zt_-iW$;V6M%B|9@@UGoIXzN;pMqCnSRg^J%n*Vx!|4V8Q#eD)>5N}!f5E_CLii1SS zgan4r57fvMwpBkI>}Qdmw|>4HX)97a?e6a0+%&Scx6f1dNRLJ}2GedKf7yv;+Wzx0 z^d@B5%e@u*xl-LacA!}`B-(HCa>8L&WJ4&To5&@CF?_ z3=B^W+m18qe?ATFNl~nqdtWo4=lX1x0Fh8B&Y`^!Yd;P=}bB@N0+F$2LyzHBdkhgr8NJ!6eEh-2JI4E!)#DpohPJM>re;c5Oo@&( zd_`JB-Y$0e2G4iI?={ULDx5K({y1OPw2`TiC<`q;4zY{BJi9jEzf~jy+j}m0A3eCm zM<^7nB{uKtt#&#%?d=D7AyzuI=;g8htF<5ZA|bP}r^s02X!CeRREyG}96~Z{RQL=o zg8)LhnRonUPL_nQm^?2(MfIIe)bCy2+<1OUEOCNHJMd`y0b&;*#NwTL?S-89W~$T}y%v98 z?2bj}Qq-H)u17$_N-tr#Yo=kuTb=hjt&eLPZOzYDPG#Ku{QR7p(<>{F>O%62MTuyE zkd)CRSz0!BK{eLX(nLO=v+vq&l(kgJHiW>n9vle}0_fP#+nZGZ`f`qff$`OY9wk?P4~rle4KgoQmmJY3vAaWI?xO*vWFa2*(ts%JJ1fZ{+= zrWS&5kf4lUg7xe5{`9dMLxDK*>!pnC@)IrzBUMXo8atvHo35KNuK}hx@x0BAOE~Qy zo>$}cERk4jS*bxvq?JnIam2-kNukGxs?yC1DXG+urOd4!Vh66hC==(N35hN>x%G9> zJ7G9Q1DW$x+Uc$+edqApKHkMW?&pYLnDuBk>LnFfner|jP2SONJkC`~1XHN$GTPaq;Y|#yvNB$eq*K-Q68d3)!D~yDz+8`-NB}kEl%4A_eO(Mvd&T zNT)Xb)ji$C_AP!0>uNZ@vupOCFnpIIoz(XP7U=A=iFrH|1=Pg$S?MQhq@xepC@nnO z`xY#4EjCytEO2=|43;$B{BdJVS$Wnyt$f-#{g;dbb)docN+wW8H7}En;C0)%=Jy(- z>wBFN&G7q&uyb<%hMo}$4mLClo7{xXq+thN*To8YI!j}7W)-()@_nt` zPqs`i19$h^tN+5q&+oNX);ZL8ab~98a;7-jy~Fy24g+U#`EeP?4Jjo;G@yrqtH`a6|$all!dLIb%~xE#6w0&DaKIR-u{$hIOZEmEu2H# z-?v=9$!=LKl9@|OhNcI~1=yB+L=aS_(n02X);sK07|f%BbG2KC?>NzVv@LlBY!fUS znlO*Djw<1ex9xiS5?7cP!T@#hW|Eedrze~#_-ViKA}4Ajx3owXorzN?u8}G+Pa;4A z+WleQD0&f+HPN!Y#9OX7crZ$1{km4RN;ddqfaSKy4{>a(X=_@xE?#}bVMAy=c5)9+ zsy&N*7#ZB7(1UNmj%CT@^Nw!OF-`5XVjh9BO=M9p4P`j_uk@7Hot)%7iyjStSTG$rS zY@CO85O{caEw?XD*6l0(@wjRxlrsG~;84Yeh(HJeukTBYrrYs{cQ~So#)GFoEdWA> zKR1o#9QMz{s8z(@E5ej7{rwUxdLnTl@(K!bN{<^T7na}Ub-Rg;5XF5bfp_xdK$NGy zE9p@W9A$bNwSC^tB6w7>c$4m?D`i`M<#>M>K}<;vs|Yd;Yx~_r($^10D0NTs5udtht^4 zN(g=sglkqjJaY>R?iIdjU?d+OpO&VM1oVLZP+U_yQe8U%OCdX!wA2<;JbRYyB-5(?(V)7AL4BVc&27Vm&3;0C~QdZqA|5}+`&TGDqVUW&(FDWSr zXFf-FFTz);iqu>5-ceBSb-lii?h$0C$>dk8j6HSMx(-G(9!Sgauy0!vv5320^F#TG zmETyPJ)UzSuUxjuaOASkHAOc-o&KQStWcvk$p}w}Z zz$%-X^ZV5vDMG^pu`b2^Rr#1v>u+ms^L}?U4coelmv#%n@IF_TG&avC>M*JapFU-0 zzso@tI1i4SZ&fXe>^Q2M&oJzLqlF{IJP=?C##e_;Ek)q;tv%lQ+~rg@4xS+zoa%b91|wkU^JcW1^ee+t>bE*ImuI zG#ngg-aOM(X`?D71G%Ktq?pgO0@pz5_W4H#h2Of-LJEdGaQAMdt> zt_I4eolSmq^`z9y;PWONjyU`!MoQ(k)3(xCaHtZSh1lUV!AuH0Iy+CxHOZqNe=M8b zDEK&Osc2#$%fD22cp#>67svQvGyv&1P%>Dmcy&4WR@xoblfCoUxw&U&W}NFHHpIa2 zbcnz4D3>Wl=Kz$aNiMAKA*ixbz{?yde)yKSfCeKBI7$Huh%vfnEwA*~) zOd(Xf5$|O`Iy|(_y75&Wiq68p0p?9S2El%CbcO#98MBt3D+zLyZCd11UMw) zgR>lMaE*l)Sq2qU%DM6a7X8|+EG_<~nFg3)t5>69_>;vVhxZJ~^rfQ+ylv?d6usAP z5_znBdAO%sw{x5I4S@Zer)fTY{BLbLR^4*7XMU!I%cyI-4gz4Wo9HY31iu^E_Lb`OpRV!aJh#GvTUH&Gbg+=3 zG`(ZA?+(Iq_OHd@vb^mw$8L|rBIn&w01QYF*a3~qIX#`Qg_oypJI%XA zwajcG0GAP??_x+U{zAKVr|qqn8BZHpn7O1f-=6ixbMK6qR&|R|EzM5<{XRdnnG8&V z22YkZW893BKJYJGT6i=tnD3!fy&04`qv{1botf&D&qa$6xc)N|`D2<|)j|S&^1v?E zh;+r$>fWt4E>dMmik`%bqmk)y{JdS_+j)PJW50IpfL^p;Dl_Y3!Yp076K{JXEc(^& z@ylGfp#cdgIb3oeB^CN`ftmUVNek-0a!*~ZZG|MJPDGj`_{}i@#(n5LqX7QufHW^I z6rf>)QG`WSdt7c-zjRG%4adbT6n^xEUTkRW{w6qc#D4|bmHR+{(HAuQ?)S1AIBHET z-f46qg8^JM$ch1~8T=Wz#C8Ny-U*AIW84svJY_AC$3IVfU58(O$F?|Mi>RM9qNC6$ zWBavtKBH#43~_NdO_~yFNlV2~Y?9)?-mNpJ+;o`&9=!?@W4oQ*29q?jc(nU)|K*9r}TH)-{#V>}D# zuTNA*>3JH8S~zO>0Q=V!2Qv z<^Ud>G@{gByLE%h=m+mSyAAGn9(T+0mgD4fJ zp=98yhZZ^WEt~=`?mx6&&)xlbPYc+`u&3PAX-ba42qxC-{APOixtbXtO-Uq5#1AuVivdO)nIzi)MRDzccvL~<{Eb@+23wunf;?=(6*11(<5bk57)?G3$w2g-;e z=U!Ao?~sj*4vvOrYpE>~0aIlKN5}-$tL}CjIbDJFZBpssh4aKIg|o6P!>Z&znDv`0 zec@Snf5eP4Nj$H-yu74ju9ukEfL2bGO%a|vCMzxT7-I-&WNTRzD&^S2A zojYTk{wCujt$u71s;sP)s<~&3gHyYXmA2pS{0j5<>yoDzNqRh|bGl4aMZs(;xoI&| zWGO2l<#mzMd}_yX&mxWpW-~H5dm`W$o_yB!5Gg*fadO0 z{`gkhbnJZ6`ormJY#2rC&j1D_LQ0_NZ+L-;t4!cv8WnpWSxw)lrn8phbi>tZ!8y&Rju(+U}VW(yOWRKgJ=< zxp@iJT8~@SKQJKiX>H|8HagZZfVi|zsQomh-Vp&<_9X*uxbx|M3wMs{mcDu-oh-GW z&25%rFi)phf1#tgFt}%2iGnLHvn07ZU_c!I9_r4M{?vf*_;!JQ%(8WLW6m=!>l|g{ z&QLL{Li2Iq{05Kv`uwl@pDXLx3=y6h`q)bKSKR;Y!n9^@m_)1?BZTlOrkU%!sJrQv ziKi_yeEaUsA~rh(;xxGy%YV+-vsX)ogZM4q zh|S6lf)n_Q&CGI0S`n0UopvJ>(Mz35oy{Jkk|T2toD2I}#vL zQd)WY26krZ1qD?A%^a~R@Jy0FKDqs~De0}rCJZ%p_{;nBkOhFO_lfAKR(@2aq?uah zOQ0D}Ksu-#1OS5lae@KEGyQ;Xd6sWx%g$H}7_6>4Ih*|Ue!OoKTz@kymh{=`+GW3% zTR8srjDRsv`Je8bU;sK56Ox2+qq~9E=_XQ~J|oX;!RO7Gna^V;7F02iUcIrb15R2t z)^O9QD(Bgm?Fivz!SHP!#10G9Wv`SLliKA%vkQ5fDM~&b;04ZO2jm)hE^5KP|{Ea19Jh z7GP>@Sb8bWQF?H0RoWh1oH&y0Ecru&t1Je)200d)$RA*Q2+k}7Tz*lQ%xW<=ULhn$g7aCb%o70Qe_QL^AU>c?I;I1TO9gV!ln5bBIRwa+aDxkxar^K=6S z+3_kVgfe)&e6y4c@QPpCTf-%Ep!%V6DN{ZuOkVHb;JsM(>BT6iF&9MX5cP4Dc1F(cL zCBuGUkxv3l+zel$$oN$6@20np1G~?kAn8UX$5z?z;o=z9_2JV9$wp;vR={m}KhYS> zAA^5)&c>TY?nbGQvVp7iTsM*y5f1c1?C22kk*;*UmMKQva-O{}87C!H$B z8OHEwC$_uL{b~`oSloC6BNduQbdU3g)P6p?;Ol&Kkm3!Qb33%+>)&9hdO zvxmoSD?%-r+IP$82;s-JAiPj5(1NPKx4jLiFdJ2eW9ue=IR5~ zdwG6`F(ci8y;i<}CHl#Oh~cQcqFqNFNg32Sf5mfp-I>acF{ey%lzvNXT_9%gZz7jZLv}9+dqh$H-MO~l(J=lJ9LuF>mZS66RT!* zOY3+h_X(z0UnGz!Zuxltz{egV3S26>#N_YS$GQqcyd+U>@eD=ntF~YyxSUtN{=;XbO9{zp^xti(xbz@XtYDQ z$!ag3tf+V9(6UUI+{X8Z&Fe&A#C!fbZ#z&<0DX^zVI`Fq`jL@vmMc!^xeCf@X^{Fu z5lmp(T$)juiap|i5C;{u{x;3QSWU`cA&dc=0CLbj`c{uU`7qEM5U>^!sJbYlXj!B! zQ3igutecuvd2@4<^|P39!Bc3`-b+@B@{l zhVH>3e7S*7S=j0Bsj~ky5DoJNJ40NSkFS`0XEd$vq(rofW@*2eRkapjGW*L)D?bLI zPc^+*g#?P1BCZOhEY*J5vmFG@K1HBsXoM$yC-yN{mEY?h{# zNwBvl;Fui#)s50;yhva4_U62il-U>%?QMdWcpUJ!l+e2Lh-ke z^{7!DoB1BNx2Xt#w8@33n*OmDMLO9!cv&yMVz6=!| zMSfZRcK>Z$uS%;-Jv!|URS703!KqDyTLQIK29#$Sqah$9^^Ro=&>igW!zp)>eJ`eR z3IsrA6U*CwKdDvH5&UIb@#zI8->6s`ivg%!mRbI0&a5aEMv0o=482^T^YNZ|(74$p zjr~rMQwBgliK^xPKwuzqFY`n#&k?h3A8!#2PKqGqq3XiM_mr%)6)WEP)~?#}orE&n zugWCgI3H~b%vTkhp#mWvq}p{%>K^4TU6!wRmRK81VpKHZ5DZY#MS@LME)eRgNGMpy zKD|$`4kJ;fF0M%TQk3<%VlW8(J)w|@Wn6F1b_VKI4DK<1uTnm1e)hYg!h1k5 zoSp|4K^YAp)|F@&^LA(BxnoYX%!SIb4e|Q~j@IZAb6aAix!c6lznT@!ktEq)37ggS zxH}*a6TvUsuSht`tutm*c}9puVvU(C*S!3fV_$Y%Gy%#(<`e03H$~#->$U8odHpce zQhW$gRMQ7A3+v~YsH9Vxr5@VHy!Xkzj~|^kTI=U3)Y@c@Tdf!L%N379zw7Q`2+7F< znMt%6C1_>EawYD`<>ZrRQiq9hgX8ZS%67V5Jyx~WI~p2XU=(>JDYBm&0gBxMwb8`$ zp$o#)DZrkrM@0q1>;tCnfsKk>IfUo7n^+$ViMFAqc;zm*n4sXS0Q6kNMSpS%2}@-( zWw9#XE;d-jBQ-`F1z+${+8Zrz*`zl}{#;4)Zi1GThR!OKImWVYw1O8!M?Xs-6*a2< z1Bp7Bdp9sEC>h_L)JgP44;7oK(v3!|^pLWak<)t-<*+wjVFPmcH*QXXJ)#c!2a9Ec zyPP%21}9~eS}xdMM=q(2Z{{8pA8awj6Hj%I{bBV7&Knh3o6dq7x|Yp;FVoXX&*v{n z`ugS7ixzXUDKigF(^}D_?`2E{s@P~7KdI^RHWI8@HP6PncK7!NQbqUYu+aT!{xqRe zTNbsw|9hE~ZMChY#;Eezt0vcuwKP19D?AsFU!X_jNNKk@1ePl zjr<1%L<{E<-5g+P{>9t=)&ev+#cO|ODArI(I$oxmwm-_Zc z{>0aWZ*`hB5^}offlIBPFW`GVQira%<5>@lHp_ZKw^Jl1CO|6O;_%R4W*DbQ8#CTpWB+7)H z`g2m&Ow7JsxJkNLAp=Y4ilNA?#_(k64{8L|-9o8$h9(?M#d7Qe@4|Z1q@rTg?Z;kk zq{z z{Z)rBUiU;-i8BrnebxqXvYuD?NXig6qvhp!DXkaJ-y2RZa&CEgp$-lVD5Ax=4hjn# z0O62HToPPDJ) zG6J+}0rhuIfL!2j5J?=q6WTDjd)jw4gHu+628`wJSRnQUf4tf;!v1hD)L~gYcHDw9 zjoL_`aW~>^upFPif4Q2VfRZBaZ|Q1~bF7*t~jpbbGk z%3X4AO>y_$`hGB)-1YSH*Ty|WfLbRA@P$EKhe?m}xZYBY;;&OO^A15-f>d zq!N}(HHE+wySg=A0?C(D)L2?aMp}GBYY-wNJNxW-C6!zMykV0kfFtCOIl(!cB`k?_OAhM z!IpSo+pL5g^2Bx|3<^FXwCLV3)VEG8aLZS%&B-Ce@urfm4}|7$92@nf?DIC$SqZC|8d)MYf0@b0oiVWxFa+#|pwA zIosJKqlNGlDJmEI8M1WxVKFs_FDU4cWJ#qyG#_axXI-&7g2;#(4%P*{UbH(g&%;mO zxn)U#DQSmDU`dl5RJp(+Wz->^M2+1C^6P_qfu*r)DTB!JDl0lzO*4KbLJC002wjh% z*k{kfagN3C49>WC`EJJ<{L67!n+-{X$;;CFP1Ccu`szE-Cwq3qnT>BW&&$WhAxtH4z+)aP!3M?Cjm$UHAY`xq?{to$Z{!AEO$W`ABCjt!aovHjNd zJtr>a%L1;0ge$LW*Q2AYKvea)kRX2CoM*$VzjP7u__#N|sDTHO z*%9KiAS4jv;QPkc&PV-25?E^oSEs#VY8I3!9<7K93kj)Lvx_EWRG0u3Y%JY(y7Qca zX!IKr3GIwhPDCLGSWl6B`sn!jMYobdz%snA1SxJ}C|9nV&dAh((W5uv*ZIOVoS~ic ziGsn2aT}W>FV@}c>1?)D@Uckj$CyaidZoAp0T}d88KJy-!=lR1;r>YB&wQ;zA=}ue zA&g6&WvMgX0YeIT!3G16jghELt@#Sb&fh(qAg4@;4qG zZg=(Wx=aWK{GQsiC1V^n-Dgt9g9v~oc!%hMN*_JAoIE_8m%(*Pm9+$eLC6)2uNm@ z86!idWyT67?xXPdB$9IqAA4d-w&;re+do-*nJ6eeu?_POfe`p(iG_fMen(?hZO2V{ zgO1~KY@8+K(QS0~Fvj2w`_Ik-WrnMpn|E-W>uBcWbkQ)Q==E&wBlpifdSqkk|hQE`2N+YL16e1}vK$6ag@B!9%9fZxC2{#(Sb9&R65fjgnN zsFrI{c|5$$NhFxBuxYCOh>PTzqx)<5CH=@;;-7t${z4vl$1gR#&lAtVKd4z7)S2KG zn^q_7J?0>Af~k|Z0eUh*(Z}G*_V3k!k*$A)F4FADycId<9|Yr1S@ab!++SG2B&Bi! zQkXINsuns~vyKXoq`Pq*=?BXVqS$_$BBj}{*Vj1@3Q}5nA0AIhhlFRzeKN^Q6+m_j z{()<5@GVUf@msoOG&@GYK1HoDHm$^f=I4+|80eqkLYf9R_y_0f+{5&`t5r_I!&-JG z4p|XLp#rvv7q;Z_o1VPSrL z_*AN*&TnXTu*!kfbDTU~!ebhRIi}eXhqj5-k)YaAF1XRYL<2@SELx8XIyyw)#-|1_nx~jVO+H2j^ zzD{h^3H|lXq2)WOE5760fd8sjYP*VM#aibJgqrcZwx0nDBjC1e((+1%QKkdh^Jo^Y z=Yq~})NIx8d7t0;fy@*Uvqi-~Dyhwz?QcsYe+Qc>M~sDFx=ADSq>B@|diy)+K%M%= zFQb}Y9;Y@$Bz|WXR#a4|GXmxi7G`EN6h?(`)fmdEdb3k8eyFdAq?*!Pxl0Cr&-Ti- z@L*6GH&YX1Vfz(ogqAOoW&zhjjC8U+tY4{22nhj*XV{q&vAI62{@#%#q}_vI z7l-_l6e(q4Ei`N%A4M`PnFx8A^NY+KVFn{AYQ=qGircn79bQ;PyUW8iyM7E7JJPeH z{=j%Og}SmB&W#2_UflFU$7|7LSxbC61-)x}X?x6XEmT>j{t_>15D>e<3Wc$K9CS>`0Rm<_Ex!xA0v;MQ%LPb; zBBnkJ9b7-&zl6T)BB-K_@58{y`_etyZd37Mp@ui7rN74{Ow7WZK5b)!dg12o{&vFO zjNl&5{+EY{Y(PSY7cztD)v09~i0pNK9^c`3U=QwF9>{wdR^$+iL6At;aEAxy8jtTC*#a>(S!Xainc_h}42HsC; zdv>laE)OQi;$CE9_OGFEbkuAX%JuELa>P~=Dwz~2zPo3yc`+H=OP3wK`Zn{mx!(h8 zp}3$HpxFiZ*e~k=BNLE0#WwA|Pz3zG{6HuZh-uEq^PfU$CWP)+?I(WJMHShjGX`?y zacptKaTvx_*Q67VhJZm&3Oq}5ZUR_rXok3#k(Fap8u&qN*fEzC?J>$uj6uB^1rf^7 zBO;J%trEIul)^Rpuhvghcls^zoZtt4bKpC-ozIJQ8fYxCV#i<`FMhB^YwY0;_d`U6 zjgu6)6@K;F8@6TPU(o`29{e2p* zky<2^r0HTItZy3#K?6R?kc>AlevqzE#=UEHS63G>nZN@S7<*1jAJ`*(+XUfqsr z$P^qTWeVENZU1V=V&rWru_7(1TQC{~hJTdAL~*oT2-a*7a-WXgb8aQHAXGB@UZovV zi4;Ifr8!w#*56@6mHHveQ| z@Rdb@O7`%>F-Rp4F?l>Kgqcx#fJh`zhD40eg)W8S`vp)srD7CNdMS_;!y4k&%I*Yj zG(2>?B_HK}7gl{eRX)n$Pe+rO_e&mOPJNi-u1}?^?}ZHVz7Y-P@1pP`ln`~aXK^Ab znm-;UBzs@{d5*qWDq0}*nJyHR!}J4x^3CwXwIe5nipojQK?b+xVIMJXxYG8;h*L8j@JQSl{SSM}>$fve$8~Tn4kjhZNk^(*g6Y z0c5KbH(yQ3DOKD_C*btR(ziDQH+&zE7*603!mIwB6f>og9a0L0*&mB>S^x0T*4FlA=d*cP4y}yBhN|{r7&@`eobJQX1$V{XI&P-V zGlctLRjz4lX27#{Uic;O*!mT<&o;&6b7Oz~@U+qB-${n-1uXy@^Ut+?d3m{$h;Z$Y z64vx??1~~OZmoMUOXGgF1Nx9t8;4x%VR1n2ZKV4uf9D?4>6KUDVPJD`KDP=~W@y6V zE4NiO;#IY7{|(sR`(r6zGBTYTguaBeT=5qv`5?c1*x@cKO<$Cu5VIM1(V}aa;ZEad zIGkvIzDMQ+Veua*k)DB_D&Ly42G!cFug!tj`JYz-MVUa|LO1sVx7y~{bTo|ynqdPn zD7-Cs+K%H_+DMRYR=U?w^ZXdMJ{@61_;yvQh|`Ab>4vc9CXJW#<3>5-%iSM1;ivIM zO>Zg%1adDes+6%iXK5j=M(;0!y$;`pcV;RGHIg`LLFu8kMQ9gz$6zA#Q>yeH_3nkdu`q z@+7_P4V3s+tJqk%mOREJusz_mRDyv4&Qx%4E!J$i$FBdB-}1+p>|*nIGfNn1$Ab7c zY*N$jPJlAf{U-XJqh;dcf-ZDy+2)T}cIo0^oHX-#-?kQm>SvoTB;;z99F}Ta1 zXCxn+@LZWfaYaNgl3x;$a4$SW(C0s7JM27n*nd^mAav$pm}nolO=pOG9T^h5uWz>- zoBsIL@wo96wyb7l&cZdE@i${EY@$N7qmnlC1 z_n^lc=W~*5zhzo^Jie7@B2gq(#mb~~m`lG09H~x4Gt>H|;$61AUyhNsG>MDN*1}um zOT{lI+f}1tWVNO5X}#imn}X-a69Qw;q=2uUhOIa!7H}9P$r@34-&Ol>uWIXkCUVmx z6?U#2#ti~v5k0UqIB$0{eBwE-?i-e~89?tzpAeDBhYF`MVG?nND&8AI&v+v&H*c<} zum;E?dV1T5Mequp$Kg+&f9NDg^>j&(r3gY1!G7P*m{g9t($4M>P7>17CX5wmhn}hi zgx;3cGVD(S)btV?Dn%;A6e&zT^`c0M;P|%bUDChT<4R$HZPJPqbR!xvVEe>Z&7;(7 zz0sqJ7}!_ihU_TS%3oDqI*gO`hX$03*}_i}QPJA|c%EUceOdPq^kX~4I;^6F>b1XN zWuvkDGDB_l^^St!?Zm&%`$ccZoV(5m@`t##CR^xAc;C%^n}<10=H=xDNbF2>2-utX zBoT)9169jeyZ1d!dpY_zg3L1+bD&I)5##$3+M=?Cay$~)L`&4WSQRAX-C`I0YQ|pMX~tG-&9{jL4gj3U%yA-J z(7nSm=kHFz-1uje?6`?oU0D3AP=P)eokIu32${EAZEfL8|EmT1;_sk)ITyJv zp9J;K2MySOiBVQo25=MwSfUcUon1}89!_fK@NRIr?FwC-7Y)>nJ3|qhzdpSFI&9gj z-7#2yg0z>c+n%;$4JjI`8x>;bLc^M8oA`jp#N@@1va&OY@UHT*x-U$eDp?Ncq{^oX zwRs%YpP8TcEFxW#-`k(Bx3yR|Ckb7!uGYb7Vtj_84*-1`6OfUUi0gMHFIh$;GLnuhZ!iXzf0@+s0Q`YI8`;ceKRwP;NwN36TK?im`tXWw!= zO_v;LzimTrNJbl^kQ!yC1|SiYcudu;m*1CmK$t*&ShK9&`|Y*O{hmwsn#!{;e6b$+ zvpEVB1!PkSjGr9}D=tY4^x)nb{&JPx|I6<9OW25=wA&VP2T?e0WqBDFJR;tRi?=nv z&W{)AvGv!sKhb%bSKEv~0x(&?0Q7hc4hO6P-cmwPoF#X{`3=cVBBTx#eC zhT~T3T@eYdTW#QlE&p7d#Zlp8bCzb@uh`cx0N0P&e{VoxxO5m~7QiSbDo#QM4T3_L zG?H?u^}h0M-@D)N+E01c^j8@-J*jEQ;%uYC`~GZg%=y|rOP>-58i`l=H+6V|}7eyMqOcE_B1V653f<8lMXWF#MLU}a?m z?4*X(nw#4cwh_)e2O3_|*kit^3*CdB*YM$wEo2 z<9cK3Pa-?-7MRzr6~pA{xt#Lln02w)HKN38*0&7w2m)P%bT8;8toNzwJ$ru7x1yXMC7yE4Ipi=P5w>~3%j<-z^e!5V%h8P_Go5Dsvyw{4m{37M@|y}Hp1Zqy za8MA?T22r3J?#xo3TI_tU_d}8Nli<$WIAIS_bhQfqzB7UD=4HXZ#>bX-;EB4^$HkJp4tN3@}UO$N}ZCnpsFfMAunK;JSg`Q-1W z<=i;^yg` zeYvUTpiR8m(owJFZZ|FMTVSS!s$w&B;kqPS57d%3H@_ny(9qC?JfX}_`&K)=-@5z} z%(*xE7dGgf1?Z)S>hMP~kQ^HDqMm@xWQW8qkuaroNqv zk=TMZZENRw4vuf1AP|Tz41yEn=hOU}%Uh0yt_W%&-wsD1M=_}GjewTe2N}lInn>1eSW+LQQBj4@k_fs6B5osWY%1%(A!+MBxV$xQ)u5)T zx_@x+{{8!tTeoWKAdH zxoeDZIS#&J*3>pBnaPeWiq%3navU^ZcAlUlx|wD|ESc$uQ79kp69^XV&9i$ly7k>i zX57ur>DmJZF~8I3_&CY01!)XepaTi)PA?b%y34(o_QWwGdoM39V3V4f7FC%yv>k{x zA7JuUBHq?p3-{CwBOoJgZ>a}C@1_2}>Hd(iH_G%$0RMB;fib{{f}EcN!hyoE*!Jb^ z!Q*7UW*G^OjSg_Bh4!aY^rB!VNz>4Di<}?u#;!ymH5;xmSvTVd;wQyLv4rbUt&mpK@T>9HXx(_6SRuuTrUtg&&Cdg4ZO zcXG=}e4Cw{``2{_bP;T8C7bcOl~cF2cHmv6wNE*f6+~R|GjNdakAW;>?9(z z4shdb$Q0t(ZXImZmfo*;;+FnD#+;P`audnbh=P6cW8kb=U0hroFkO;4m;+U;@X>p; zNn^=*gLC2wvrt*kPRoYKk_lLAGiXmrYn~5cp?%w1?=;kiN*f-dKD1o>v^lF?Es7@K zlhKSLVe<4q1~v2!e12Qw=-G9SN|b~ydNBm?{r-d)hZcuci!PA2)8|)N$HwXR_8^=e z8VF%;C%$#_w6$fGo7sUG`-Ji}Z+fa{0MpAbXG&dDQ&USz>p!k2b;RlV3kN&P*O6)2 zPW(zr%1jUi>bHPCfjj3O9buH)6Ivi$A2YOj{V0<+z3^|S(Z{75F>Hr$Jn|iAmd#I3 zPp_`7c6WELitW5=Urm`@HK?Z)C}0zQZw3sYsm>4;{1xGRr?ZgBabXMN zlt3uEA+PGCTV>b}6XzROHPs;ii$>CpcQQZ=#jYhJ-QN)+ZToiW2t5ZiW?M`;f~F9d37tbwX~hBSL~nyzKn{Wf%Ol!q@zhQA~B z;kshjtah_{TW;2|?=~BhzTS^*`MPQq7xfie^&@WQRH5aA3gyF2%;LX*6!`+pHOh9K zcL{KC?8-|_!g%Qo8ntQ#KmQnS@xc45t-dn$=&>#y)WEsPb6Y{nUeQDbFh|Xo-=Fvz zo>XCUJVvO4KU(t}zBBFrd&|F~wuVb1SsK+SXB#Fb##Lv5lEi^BD&g%|S;DJjs)}rc zTG3WCkaGWVhw||%e9Q9>UaS&5;-?EvUquAWW00rTShoauZ}0dp%d5`Tz((_t#=7EvGRmXQzWZ>AP$aCm zFlrrAH@4#(XkR{M0-XBmHeX&wHt64FMsO61z-7%t9f|~FWn2{ee<%~{~ETGLJJ`(Rbq_%p9@k0-=(747@U^bDF6VNu1NgQoz{8v}@^ z8(6QuwPTpCRxFr2H(T(|JP$Vu%EwsLa!6+jIi0R3$ci&-$^sX8b*m+rdDUJaZ3PwB z{$1B2^L-z$vAK2e@xnfnSI<95jrN2pOg*}+AS{w7qP^X54)UyeMD*dwu$P>pucpf>>QGX4<2;Tn!}7yZT1tGnn?jS1rx~9Ub6w{AW!933>>;d_4;c z_n?pz%J_J^_MEX{gMQ9T3(CWRfyzV%DZ0`;hY(!5=|N-5aTwBOS$6r zeyNu2DJ1`L-8k?0t`Cm!2=!;^IC4~G0)c^5(5#O$?YK))emlPQTHUhZR}qMhFSi1;etUck4(=2c|y2N zsnV^+F=>CT=*C7WX0KDYu%EK_Zf-!ZK2_p=9@`&Y^ukj#vhlHEZ8ndiH2S%eE+Y!W ze(CJ|ePWR$V{o_kT_@L76yco~$IkAraw~c=9ozWuC?o%w#Y)o_4qi{?G9~2T;9weR zYI$Zqml;iG;9JYdwe8gT8(Yc^7L5-Y3^cM2(OKE@0wJiOFAy#fgB~u3Ms0}|AQk%i zI6{beSyL868fTaoj($}hjTm4Y% z6v`oZu*G7K-~pthq0T2z9o)+&jqTKrln2qmxs=K{J2|;-r964CqW#XCP{1wM`a}-R zTe`XfLrATwYqXJH`M=30b2qW(YY-#dCL&~*kK|6}9xK@NO;@qfDDRUh( ztnEuO!q2W7h8_Q#g*<%1DUEN#HB-=bG+7~qpJpv%eiWxDm*Q{y=C9EnMe9YX1g{B6 zr#o+dMk6QWjY4%F*HAl)w5qNX6H1*Th@I!dP;?gTPWQNo)t>G$#5(uq8GtM441|It3P0IFy?g!I-xOlp{BNlxc z)qwRlPT z5>>HpD;Zn-s^GW80s#5IVhZzkvI1@xq{$>9H3_}W@MKZbR-VXl(MOT4OvDtoctQ)? z!})%g&IC7H`E|PCWLI5l8&hJi?eQvCozd+n8da?HzbQ@qE|Zjy#x!1I!Z-5z{*e-_ zBy&P4qSA4HAMXDy{C52J-#r@R5{A)#VtuZ`=w1S)zo4&LgMjT+_P@`g@;~Bzo@)8^ zOVYuhta2yfF!owBT#XW0Y|f0BV*ZUs}y;b<+J9N z7J%~t7}|metN*PbEsnC=2b;ZTmWKIH*sPc_*wqk}nCs;P=t8m7itUNNQ(c5-S{mry zyCdA+-;Q^#O;@T+W27yx{-9BB+*dbhG5-k|E3iEI>=}Av9DoaaBdOUx# z-f(t4BE1Oh0Bh3W`b^81iven0G${pW-SgsTlfHsU1vE7g7E$bV*ZV{tm9V=;s zu&@BC*pGUPqx18POyu={i>jOulZlB*@aBTT`#R+A?8SHf@C7pu=NRNKVp?%VlsV0( zSSVtSC@$csynl5qQ=nj25R@b9q5|a}eKqb6h<%pY_CM_3N~QJfLJSF8oWhD;hOgDe z)8&C~F<=h@Xd3WE$N!F+Yr4Xu41h?dKhWXX7^vOika1sU2jo6JfDvzx-c|^MZ)HKyF;i`^(AMm+HA@XecBc z`aqn@X%o&u5jZINaKL(uiw&rJb+$&SMKLP1+z>DPX?++B) zdv?5`*{Ev(Zx%TI8d&Y4DFH7n3!pk+)03txIk z$cO2#6T!~nus%={zBqRE9eR?_GhJs6ncJ;eKml|PcrAeb7Vt31P9-EZBqXiYWg()- z=7~7DeY*NL?8;Qbc6j7w;+lUHZ`lzOTCRo0RhclcW%>XfqD;kXjBJrB4d(YnN;Yv= zxYa}^#IT|`pMeae`o9dNuqr?iWltJ~_xQI{+H|rg-IzJHjnUwW>x+(wiA8aE1ju)i|6|(qm^L&FrX6HX>rRg3GrT`;gs( + + +HTML5 Submit Buttons + + +
+ + + +
+ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_tests/issue5237.html b/test/ghostdriver-test/fixtures/common/click_tests/issue5237.html new file mode 100644 index 00000000..464fa113 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/issue5237.html @@ -0,0 +1,9 @@ + + + + Sample page for issue 5237 + + + + + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/issue5237_frame.html b/test/ghostdriver-test/fixtures/common/click_tests/issue5237_frame.html new file mode 100644 index 00000000..d6f4caf1 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/issue5237_frame.html @@ -0,0 +1 @@ +Continue \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_tests/issue5237_target.html b/test/ghostdriver-test/fixtures/common/click_tests/issue5237_target.html new file mode 100644 index 00000000..cbc16e85 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/issue5237_target.html @@ -0,0 +1,10 @@ + + + + Target page for issue 5237 + + +

Test passed

+ + + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/link_that_wraps.html b/test/ghostdriver-test/fixtures/common/click_tests/link_that_wraps.html new file mode 100644 index 00000000..04434364 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/link_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_tests/mapped_page1.html b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page1.html new file mode 100644 index 00000000..245f0385 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page1.html @@ -0,0 +1,9 @@ + + + + Target Page 1 + + +
Target Page 1
+ + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/mapped_page2.html b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page2.html new file mode 100644 index 00000000..6f9636c5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page2.html @@ -0,0 +1,9 @@ + + + + Target Page 2 + + +
Target Page 2
+ + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/mapped_page3.html b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page3.html new file mode 100644 index 00000000..87a35f38 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/mapped_page3.html @@ -0,0 +1,9 @@ + + + + Target Page 3 + + +
Target Page 3
+ + diff --git a/test/ghostdriver-test/fixtures/common/click_tests/span_that_wraps.html b/test/ghostdriver-test/fixtures/common/click_tests/span_that_wraps.html new file mode 100644 index 00000000..77a9d6d5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/span_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + +
+
placeholder
Span that continues on next line +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_tests/submitted_page.html b/test/ghostdriver-test/fixtures/common/click_tests/submitted_page.html new file mode 100644 index 00000000..0ed2cbac --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_tests/submitted_page.html @@ -0,0 +1,9 @@ + + + +Submitted Successfully! + + +

Submitted Successfully!

+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/click_too_big.html b/test/ghostdriver-test/fixtures/common/click_too_big.html new file mode 100644 index 00000000..568ee77e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_too_big.html @@ -0,0 +1,10 @@ + + + + +
+       +
+
+ + diff --git a/test/ghostdriver-test/fixtures/common/click_too_big_in_frame.html b/test/ghostdriver-test/fixtures/common/click_too_big_in_frame.html new file mode 100644 index 00000000..cda990ed --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/click_too_big_in_frame.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

This is the heading

+ + + + +
+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 +

+ +333333 +

I have a span

And another span

+ + diff --git a/test/ghostdriver-test/fixtures/common/closeable_window.html b/test/ghostdriver-test/fixtures/common/closeable_window.html new file mode 100644 index 00000000..e64c599c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/closeable_window.html @@ -0,0 +1,8 @@ + + +closeable window + + +This window can be closed by clicking on this. + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/cn-test.html b/test/ghostdriver-test/fixtures/common/cn-test.html new file mode 100644 index 00000000..df846ad4 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/cn-test.html @@ -0,0 +1,156 @@ + + + + + + + + + + +
+
+ + +

Õ¹Íû2008ÊÀ½ç´óÊÆ£º·çÆðÔÆÓ¿ ¼¤µ´ÈËÐÄ


+
+ 8ÔÂ8ÈÕÍí£¬±±¾©2008Äê°ÂÔ˻ᵹ¼ÆʱһÖÜÄêÇì×£»î¶¯ÔÚÌì°²ÃŹ㳡¾ÙÐС£Í¼ÎªÇì×£»î¶¯ÖеÄÎÄÒÕÑݳö¡£ лªÉç¼ÇÕßÁõÎÀ±øÉã + + £²£°£°£¸ÄêÊÀ½ç·çÆðÔÆÓ¿£¬¼¤µ´ÈËÐÄ¡£µ«Òª×÷³öÒ»¸öÔ¤²â£¬Ê×ÏÈÒª¶Ô½ñÌìËù´¦µÄÊÀ½çÓÐÒ»¸ö»ù±¾¹²Ê¶¡£
+
+ÖйúÖ®Éù
+
+
+ +
+ +
+ + + diff --git a/test/ghostdriver-test/fixtures/common/colorPage.html b/test/ghostdriver-test/fixtures/common/colorPage.html new file mode 100644 index 00000000..0d1bfc0a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/colorPage.html @@ -0,0 +1,20 @@ + + + + Color Page + + +
namedColor
+
rgb
+
rgbpct
+
hex
+
hex
+
hsl
+
rgba
+
rgba
+
hsla
+ + + + + diff --git a/test/ghostdriver-test/fixtures/common/cookies.html b/test/ghostdriver-test/fixtures/common/cookies.html new file mode 100644 index 00000000..7db5b493 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/cookies.html @@ -0,0 +1,30 @@ + + + Testing cookies + + + + +

Cookie Mashing

+ .com Click
+ . Click
+ google.com Click
+ .google.com Click
+ 127.0.0.1 Click
+ localhost:3001 Click
+ .google:3001 Click
+ 172.16.12.225 Click
+ 172.16.12.225:port Click
+ Set on a different path + +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_frame.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_frame.html new file mode 100644 index 00000000..7714a48a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_nested_frame.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_nested_frame.html new file mode 100644 index 00000000..b3143b0d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/element_in_nested_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_element_out_of_view.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_element_out_of_view.html new file mode 100644 index 00000000..6f2bcd4f --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_element_out_of_view.html @@ -0,0 +1,11 @@ + + + + Page With Element Out Of View + + +
Placeholder
+
Red box
+
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_empty_element.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_empty_element.html new file mode 100644 index 00000000..b07972ab --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_empty_element.html @@ -0,0 +1,10 @@ + + + + Page With Empty Element + + +
+
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_fixed_element.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_fixed_element.html new file mode 100644 index 00000000..b8158917 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_fixed_element.html @@ -0,0 +1,12 @@ + + + + Page With Fixed Element + + +
fixed red box
+
Placeholder
+
Element at the bottom
+
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_hidden_element.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_hidden_element.html new file mode 100644 index 00000000..286b04b1 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_hidden_element.html @@ -0,0 +1,10 @@ + + + + Page With Hidden Element + + + +
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_invisible_element.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_invisible_element.html new file mode 100644 index 00000000..dc33c718 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_invisible_element.html @@ -0,0 +1,10 @@ + + + + Page With Invisible Element + + + +
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_transparent_element.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_transparent_element.html new file mode 100644 index 00000000..d0090d92 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/page_with_transparent_element.html @@ -0,0 +1,10 @@ + + + + Page With Transparent Element + + +
Hidden box
+
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/coordinates_tests/simple_page.html b/test/ghostdriver-test/fixtures/common/coordinates_tests/simple_page.html new file mode 100644 index 00000000..7b857b9d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/coordinates_tests/simple_page.html @@ -0,0 +1,10 @@ + + + + Simple Page + + +
Red box
+
Tex after box
+ + diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..954e22dbd99e8c6dd7091335599abf2d10bf8003 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEr#)R9Ln2z=UU%d=WFXS=@V?HT z#xG*`>Yvsgk=}99w^d^D^d*@m74oMo<%#FcopJf?u00-~YVKV2wzrI*_R6;UORMea zBFVSEnN~eiVA6V&z`E)YLz5Aok^D)In}Yn=OzDpgR5Wv0XfT8pOkmV{sKAJ-PO9#T zZK}IXj&Q-V!U)!LcB_3K0&C*{ literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..64ece5707d91a6edf9fad4bfcce0c4dbcafcf58d GIT binary patch literal 251 zcmVbvPcjKS|RKP(6sDcCAB(_QB%0978a<$Ah$!b|E zwn;|HO0i8cQj@~)s!ajF0S002ovPDHLkV1oEp BYH0uf literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..abdc01082bf3534eafecc5819d28c9574d44ea89 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQY-ImG zFPf9b{J;c_6SHRK%WcbN_hZpM=(Ry;4Rxv2@@2Y=$K57eF$X$=!PC{xWt~$(69B)$ BI)4BF literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..9b383f4d2eab09c0f2a739d6b232c32934bc620b GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour1U*q978O6-yYw{%b*}|_(02F z@qbE9)0CJMo;*v*PWv`Vh2h6EmG8IS-Cm{3U~` zFlmZ}YMcJY=eo?o%*@I?2`NblNeMudl#t?{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100644 index 0000000000000000000000000000000000000000..39d5824d6af5456f1e89fc7847ea3599ea5fd815 GIT binary patch literal 3762 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 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100644 index 0000000000000000000000000000000000000000..f1273672d253263b7564e9e21d69d7d9d0b337d9 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l%l7LV~E7mxPQ=F85a&M@g_{ d|GeK{$Y5lo%PMu^>wln`44$rjF6*2UngE4^EGqy2 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_222222_256x240.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..b273ff111d219c9b9a8b96d57683d0075fb7871a GIT binary patch literal 4369 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 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..a641a371afa0fbb08ba599dc7ddf14b9bfc3c84f GIT binary patch literal 4369 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 oBo%DI*Kv;w;*%(i9W@e{{5C=l}o! literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..85e63e9f604ce042d59eb06a8428eeb7cb7896c9 GIT binary patch literal 4369 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 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/test/ghostdriver-test/fixtures/common/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..e117effa3dca24e7978cfc5f8b967f661e81044f GIT binary patch literal 4369 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 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/css/ui-lightness/jquery-ui-1.8.10.custom.css b/test/ghostdriver-test/fixtures/common/css/ui-lightness/jquery-ui-1.8.10.custom.css new file mode 100644 index 00000000..1706e220 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/css/ui-lightness/jquery-ui-1.8.10.custom.css @@ -0,0 +1,573 @@ +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.10 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/cssTransform.html b/test/ghostdriver-test/fixtures/common/cssTransform.html new file mode 100644 index 00000000..c3b99648 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/cssTransform.html @@ -0,0 +1,61 @@ + + +
+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/test/ghostdriver-test/fixtures/common/cssTransform2.html b/test/ghostdriver-test/fixtures/common/cssTransform2.html new file mode 100644 index 00000000..602924bf --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/cssTransform2.html @@ -0,0 +1,20 @@ + + +
+
+
+
+
+
+
I am not a hidden element
diff --git a/test/ghostdriver-test/fixtures/common/document_write_in_onload.html b/test/ghostdriver-test/fixtures/common/document_write_in_onload.html new file mode 100644 index 00000000..a15fc479 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/document_write_in_onload.html @@ -0,0 +1,13 @@ + + + Document Write In Onload + + + +

hello world

+ + diff --git a/test/ghostdriver-test/fixtures/common/dragAndDropInsideScrolledDiv.html b/test/ghostdriver-test/fixtures/common/dragAndDropInsideScrolledDiv.html new file mode 100644 index 00000000..0b2ee9a2 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/dragAndDropInsideScrolledDiv.html @@ -0,0 +1,67 @@ + + + + + + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/dragAndDropTest.html b/test/ghostdriver-test/fixtures/common/dragAndDropTest.html new file mode 100644 index 00000000..fdee16b0 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/dragAndDropTest.html @@ -0,0 +1,102 @@ + + + + + + + + +
+
+"Hi there +
+
+
+
+ + diff --git a/test/ghostdriver-test/fixtures/common/dragDropOverflow.html b/test/ghostdriver-test/fixtures/common/dragDropOverflow.html new file mode 100644 index 00000000..ecb25625 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/dragDropOverflow.html @@ -0,0 +1,104 @@ + + + + + + +
+
+
+
+
12am
+
1am
+
2am
+
3am
+
4am
+
5am
+
6am
+
7am
+
8am
+
9am
+
10am
+
11am
+
12pm
+
1pm
+
2pm
+
3pm
+
4pm
+
5pm
+
6pm
+
7pm
+
8pm
+
9pm
+
10pm
+
11pm
+
+
+
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/draggableLists.html b/test/ghostdriver-test/fixtures/common/draggableLists.html new file mode 100644 index 00000000..f7e0dcac --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/draggableLists.html @@ -0,0 +1,67 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + +
+
    +
  • LeftItem 1
  • +
  • LeftItem 2
  • +
  • LeftItem 3
  • +
  • LeftItem 4
  • +
  • LeftItem 5
  • +
+ +
    +
  • RightItem 1
  • +
  • RightItem 2
  • +
  • RightItem 3
  • +
  • RightItem 4
  • +
  • RightItem 5
  • +
+ +
+ +
+
+

Nothing happened.

+
+ + + diff --git a/test/ghostdriver-test/fixtures/common/droppableItems.html b/test/ghostdriver-test/fixtures/common/droppableItems.html new file mode 100644 index 00000000..fc850ac9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/droppableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Droppable - Default Demo + + + + + + + +
+ +
+

Drag me to my target

+
+ +
+

Drop here

+
+ +
+

start

+
+ +
+ +
+ +

Taken from the JQuery demo.

+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/dynamic.html b/test/ghostdriver-test/fixtures/common/dynamic.html new file mode 100644 index 00000000..b9e60678 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/dynamic.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/dynamicallyModifiedPage.html b/test/ghostdriver-test/fixtures/common/dynamicallyModifiedPage.html new file mode 100644 index 00000000..ed7c7ed2 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/dynamicallyModifiedPage.html @@ -0,0 +1,42 @@ + + + + Delayed remove of an element + + + + + +
+ +
+

element

+ + diff --git a/test/ghostdriver-test/fixtures/common/errors.html b/test/ghostdriver-test/fixtures/common/errors.html new file mode 100644 index 00000000..78fb9020 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/errors.html @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/fixedFooterNoScroll.html b/test/ghostdriver-test/fixtures/common/fixedFooterNoScroll.html new file mode 100644 index 00000000..ca65d1fe --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/fixedFooterNoScroll.html @@ -0,0 +1,13 @@ + + + + Fixed footer with no scrollbar + + +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/fixedFooterNoScrollQuirksMode.html b/test/ghostdriver-test/fixtures/common/fixedFooterNoScrollQuirksMode.html new file mode 100644 index 00000000..2593bf35 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/fixedFooterNoScrollQuirksMode.html @@ -0,0 +1,12 @@ + + + Fixed footer with no scrollbar + + +
+
+ Click me +
+
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/formPage.html b/test/ghostdriver-test/fixtures/common/formPage.html new file mode 100644 index 00000000..e1197db0 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/formPage.html @@ -0,0 +1,173 @@ + + + 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/test/ghostdriver-test/fixtures/common/formSelectionPage.html b/test/ghostdriver-test/fixtures/common/formSelectionPage.html new file mode 100644 index 00000000..4890c08e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/formSelectionPage.html @@ -0,0 +1,46 @@ + + + + Testing Typing into body + + + + +

Type Stuff

+ +
+   +
+ +
+ +
+ + + + diff --git a/test/ghostdriver-test/fixtures/common/form_handling_js_submit.html b/test/ghostdriver-test/fixtures/common/form_handling_js_submit.html new file mode 100644 index 00000000..30231439 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/form_handling_js_submit.html @@ -0,0 +1,30 @@ + + + + + + Form with JS action + + +
+ +
+ +

+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/framePage3.html b/test/ghostdriver-test/fixtures/common/framePage3.html new file mode 100644 index 00000000..3e62e455 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/framePage3.html @@ -0,0 +1,7 @@ + + + inner + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/frameScrollChild.html b/test/ghostdriver-test/fixtures/common/frameScrollChild.html new file mode 100644 index 00000000..3eb3bf47 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frameScrollChild.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a scrolling frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/frameScrollPage.html b/test/ghostdriver-test/fixtures/common/frameScrollPage.html new file mode 100644 index 00000000..b7fb8f24 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frameScrollPage.html @@ -0,0 +1,14 @@ + + + + Welcome Page + + +
+ +
+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/frameScrollParent.html b/test/ghostdriver-test/fixtures/common/frameScrollParent.html new file mode 100644 index 00000000..8fccb6d3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frameScrollParent.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876.html b/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876.html new file mode 100644 index 00000000..4ed597d3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876.html @@ -0,0 +1,9 @@ + + + +Test issue 4876 + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876_iframe.html b/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876_iframe.html new file mode 100644 index 00000000..57d47d84 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frame_switching_tests/bug4876_iframe.html @@ -0,0 +1,9 @@ + + + +
+ + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame.html b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame.html new file mode 100644 index 00000000..9c27e04c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame.html @@ -0,0 +1,29 @@ + + + Deleting frame: main page + + + + +
+ + +
+
+ +
+ + + diff --git a/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe.html b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe.html new file mode 100644 index 00000000..e4b9723e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe.html @@ -0,0 +1,8 @@ + + + Deleting frame: iframe + + + + + diff --git a/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe2.html b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe2.html new file mode 100644 index 00000000..47764eb3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frame_switching_tests/deletingFrame_iframe2.html @@ -0,0 +1,7 @@ + + + Deleting frame: iframe 2 + + +
Added back
+ diff --git a/test/ghostdriver-test/fixtures/common/frameset.html b/test/ghostdriver-test/fixtures/common/frameset.html new file mode 100644 index 00000000..039c5f21 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/frameset.html @@ -0,0 +1,14 @@ + + + Unique title + + + + + + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/framesetPage2.html b/test/ghostdriver-test/fixtures/common/framesetPage2.html new file mode 100644 index 00000000..4ea35ff7 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/framesetPage2.html @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/framesetPage3.html b/test/ghostdriver-test/fixtures/common/framesetPage3.html new file mode 100644 index 00000000..42a93007 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/framesetPage3.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/galaxy/.gitignore b/test/ghostdriver-test/fixtures/common/galaxy/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/common/globalscope.html b/test/ghostdriver-test/fixtures/common/globalscope.html new file mode 100644 index 00000000..e4ca97ab --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/globalscope.html @@ -0,0 +1,15 @@ + + + + Global scope + + + +
+ + diff --git a/test/ghostdriver-test/fixtures/common/hidden.html b/test/ghostdriver-test/fixtures/common/hidden.html new file mode 100644 index 00000000..0e8097e9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/hidden.html @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/html5/blue.jpg b/test/ghostdriver-test/fixtures/common/html5/blue.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8ea27c42faa7b5e56c43d3db317d5e4ecf1cb613 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcJaWSGJLB!991Nd^WT5CM{5U@~s$UwQg1|Kd4YZgp?Ix92y1 s+ar%@&pMaAI<@T`_wi3Y*T3~X|8?&BKYkvr_9KfvcKB$ivocr%04xP0fB*mh literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/html5/database.js b/test/ghostdriver-test/fixtures/common/html5/database.js new file mode 100644 index 00000000..c6333be8 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/html5/database.js @@ -0,0 +1,84 @@ +var database={}; +database.db={}; + +database.onError = function(tx, e) { + var log = document.createElement('div'); + log.setAttribute('name','error'); + log.setAttribute('style','background-color:red'); + log.innerText = e.message; + document.getElementById('logs').appendChild(log); +} + +database.onSuccess = function(tx, r) { + if (r.rows.length) { + var ol; + for (var i = 0; i < r.rows.length; i++) { + ol = document.createElement('ol'); + ol.innerHTML = r.rows.item(i).ID + ": " + r.rows.item(i).docname + " (" + r.rows.item(i).created + ")"; + document.getElementById('logs').appendChild(ol); + } + + } +} + +database.open=function(){ + database.db=openDatabase('HTML5', '1.0', 'Offline document storage', 100*1024); +} + +database.create=function(){ + database.db.transaction(function(tx) { + tx.executeSql("CREATE TABLE IF NOT EXISTS docs(ID INTEGER PRIMARY KEY ASC, docname TEXT, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)", + [], + database.onSuccess, + database.onError); + });} + +database.add = function(message) { + database.db.transaction(function(tx){ + tx.executeSql("INSERT INTO docs(docname) VALUES (?)", + [message], database.onSuccess, database.onError); + }); +} + +database.selectAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM docs", [], database.onSuccess, + database.onError); + }); +} + +database.onDeleteAllSuccess = function(tx, r) { + var doc = document.documentElement; + var db_completed = document.createElement("div"); + db_completed.setAttribute("id", "db_completed"); + db_completed.innerText = "db operation completed"; + doc.appendChild(db_completed); +} + +database.deleteAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("delete from docs", [], database.onDeleteAllSuccess, + database.onError); + }); +} + +var log = document.createElement('div'); +log.setAttribute('name','notice'); +log.setAttribute('style','background-color:yellow'); +log.innerText = typeof window.openDatabase == "function" ? "Web Database is supported." : "Web Database is not supported."; +document.getElementById('logs').appendChild(log); + +try { + database.open(); + database.create(); + database.add('Doc 1'); + database.add('Doc 2'); + database.selectAll(); + database.deleteAll(); +} catch(error) { + var log = document.createElement('div'); + log.setAttribute('name','critical'); + log.setAttribute('style','background-color:pink'); + log.innerText = error; + document.getElementById('logs').appendChild(log); +} diff --git a/test/ghostdriver-test/fixtures/common/html5/geolocation.js b/test/ghostdriver-test/fixtures/common/html5/geolocation.js new file mode 100644 index 00000000..f07af148 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/html5/geolocation.js @@ -0,0 +1,18 @@ +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/test/ghostdriver-test/fixtures/common/html5/green.jpg b/test/ghostdriver-test/fixtures/common/html5/green.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a0d3bea4793a5fe3a3a36e29ba174540540513d GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcJqT;s&Rz@Ye(1xPY5=zs{23bCU^SwR4 t`P&|OOncV3?A57l@3@bD^11%4_xZ1L-~aLRaJ3&<^s&Q7OP!U$8UQ`xB)R|q literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/html5/offline.html b/test/ghostdriver-test/fixtures/common/html5/offline.html new file mode 100644 index 00000000..c24178b5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/html5/offline.html @@ -0,0 +1 @@ +Offline diff --git a/test/ghostdriver-test/fixtures/common/html5/red.jpg b/test/ghostdriver-test/fixtures/common/html5/red.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f296e271956d5d4e0939b9706e86b2c2bc0d65b7 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcLY$H2kBz@Ye(1xPY5=zs{23bCU^SwR4 t`P&|OOncV3?A57l@3@bD^11%4_xZ1L-~aLRaJ3&<^s&Q7OP!U$8URKdB+&o> literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/html5/status.html b/test/ghostdriver-test/fixtures/common/html5/status.html new file mode 100644 index 00000000..394116a5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/html5/status.html @@ -0,0 +1 @@ +Online diff --git a/test/ghostdriver-test/fixtures/common/html5/test.appcache b/test/ghostdriver-test/fixtures/common/html5/test.appcache new file mode 100644 index 00000000..3bc4e002 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/html5/test.appcache @@ -0,0 +1,11 @@ +CACHE MANIFEST + +CACHE: +# Additional items to cache. +yellow.jpg +red.jpg +blue.jpg +green.jpg + +FALLBACK: +status.html offline.html diff --git a/test/ghostdriver-test/fixtures/common/html5/yellow.jpg b/test/ghostdriver-test/fixtures/common/html5/yellow.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c609b371291aeb672feb6bc24497d5f64d20288 GIT binary patch literal 92 zcmZ?wbhEHbG-5DfXkcLYcZ>lD6o0aSC0GH&T#dHOB?;yGJxb#K16=Qn@b rBadm%I+wjVwe21E@lQV2zx6) + +HTML5 + + + +

Geolocation Test

+
Location unknown
+ + +

Web SQL Database Test

+
+ + +

Application Cache Test

+
+

Current network status:

+ + + + + +
+ + + diff --git a/test/ghostdriver-test/fixtures/common/icon.gif b/test/ghostdriver-test/fixtures/common/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb994619275674a361f092333cbfa122209d6546 GIT binary patch literal 127 zcmZ?wbh9u|6k-r!Si}GX|AAob+W$d8|1~xLfB*iUgX2F?R0kvlQp3RPBO#^gd~AZ^ zsa&ybSCl~e@% literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/fixtures/common/iframeAtBottom.html b/test/ghostdriver-test/fixtures/common/iframeAtBottom.html new file mode 100644 index 00000000..a686ba31 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/iframeAtBottom.html @@ -0,0 +1,15 @@ + + + This page has iframes + + +

This is the heading

+ +
+ diff --git a/test/ghostdriver-test/fixtures/common/iframes.html b/test/ghostdriver-test/fixtures/common/iframes.html new file mode 100644 index 00000000..e00b482a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/iframes.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

This is the heading

+ +':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
', +o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&& +l)?" ":""));a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";if(d.browser.mozilla)k+='";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
";return k},_adjustInstDate:function(a,b,c){var e= +a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, +"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); +c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, +"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= +function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, +[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.10";window["DP_jQuery_"+y]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.10"})})(jQuery); +;/* + * jQuery UI Effects 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0]; +h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c, +a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.10",save:function(c,a){for(var b=0;b
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent", +border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c); +return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments); +else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c), +b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c, +a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a== +e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/key_tests/remove_on_keypress.html b/test/ghostdriver-test/fixtures/common/key_tests/remove_on_keypress.html new file mode 100644 index 00000000..c0f3aab4 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/key_tests/remove_on_keypress.html @@ -0,0 +1,36 @@ + +
Pressing "a" while this checkbox is + focused will remove it from the DOM.
+
+
+ diff --git a/test/ghostdriver-test/fixtures/common/keyboard_shortcut.html b/test/ghostdriver-test/fixtures/common/keyboard_shortcut.html new file mode 100644 index 00000000..741d7f4b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/keyboard_shortcut.html @@ -0,0 +1,36 @@ + + +
CTRL + 1: red
+
SHIFT + 1: green
+
CTRL + SHIFT + 1: yellow
+
ALT + 1: lightblue
+
CTRL + ALT + 1: lightgreen
+
SHIFT + ALT + 1: silver
+
CTRL + SHIFT + ALT + 1: magenta
+ diff --git a/test/ghostdriver-test/fixtures/common/linked_image.html b/test/ghostdriver-test/fixtures/common/linked_image.html new file mode 100644 index 00000000..7c8df003 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/linked_image.html @@ -0,0 +1,16 @@ + + + + +Linking with an image + + +banner
+Click here for next page
+
+link to other link
+Just another link.
+

+ + + diff --git a/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected.html b/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected.html new file mode 100644 index 00000000..42b0442b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected_html4.html b/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected_html4.html new file mode 100644 index 00000000..60cd0338 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/locators_tests/boolean_attribute_selected_html4.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/longContentPage.html b/test/ghostdriver-test/fixtures/common/longContentPage.html new file mode 100644 index 00000000..99a45e77 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/longContentPage.html @@ -0,0 +1,55 @@ + + + TouchLongContent + + + +

Touch API

+

Page with long content

+
                   



+

Long text:                                                                                                                          This is a very long text to make the screen horizontally movable, to test the flick gesture at a long horizontal distance Normal link                                                                                                                                           at normal and fast speeds to see results of it Normal link end

+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+ Middle of the screen Normal link +










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+ Bottom of the screen Normal link


+ + diff --git a/test/ghostdriver-test/fixtures/common/macbeth.html b/test/ghostdriver-test/fixtures/common/macbeth.html new file mode 100644 index 00000000..9fa39d56 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/macbeth.html @@ -0,0 +1,5255 @@ + + + + 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/test/ghostdriver-test/fixtures/common/map.png b/test/ghostdriver-test/fixtures/common/map.png new file mode 100644 index 0000000000000000000000000000000000000000..763f5627995f6f178e8ea78e37f32c80b35f5e2b GIT binary patch literal 26209 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 + + Map test page + + +
+ + diff --git a/test/ghostdriver-test/fixtures/common/markerTransparent.png b/test/ghostdriver-test/fixtures/common/markerTransparent.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4e5e7f4d63fe103983cf3bfa53733a0089ba51 GIT binary patch literal 260 zcmV+f0sH=mP)6Xw+2uq_(M`6dHE24R1_~SA2W)sEi((o#t%gC<}F#-mygTf~{1syRj83 z$v~+4?^7VUur4s{YzK(ScPqf9AN{Mq%K}&hLakp1D8YW + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/meta-redirect.html b/test/ghostdriver-test/fixtures/common/meta-redirect.html new file mode 100644 index 00000000..9d9c2f0c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/meta-redirect.html @@ -0,0 +1,11 @@ + + + Some test page + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/missedJsReference.html b/test/ghostdriver-test/fixtures/common/missedJsReference.html new file mode 100644 index 00000000..61677527 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/missedJsReference.html @@ -0,0 +1,11 @@ + + + + Example page + + +

This page contains a nested iframe. Execute some JS to locate a reference to an element in this + frame and return it. You should need to switch to that frame in order to use that element.

+ + + diff --git a/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_1.html b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_1.html new file mode 100644 index 00000000..4eff01ac --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_1.html @@ -0,0 +1,21 @@ + + +First Modal + + + + +

Modal dialog sample

+ + + +lnk2 +
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_2.html b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_2.html new file mode 100644 index 00000000..cec3f3f1 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_2.html @@ -0,0 +1,21 @@ + + +Second Modal + + + + +

Modal dialog sample

+ + + +lnk3 +
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_3.html b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_3.html new file mode 100644 index 00000000..6c5eb723 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/modal_dialogs/modal_3.html @@ -0,0 +1,15 @@ + + +Third Modal + + + + +

Modal dialog sample

+ + +
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/modal_dialogs/modalindex.html b/test/ghostdriver-test/fixtures/common/modal_dialogs/modalindex.html new file mode 100644 index 00000000..0a1c4c94 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/modal_dialogs/modalindex.html @@ -0,0 +1,21 @@ + + +Main window + + + + +

Modal dialog sample

+ + + +lnk1 +
+ +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/mouseOver.html b/test/ghostdriver-test/fixtures/common/mouseOver.html new file mode 100644 index 00000000..d4751bfd --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/mouseOver.html @@ -0,0 +1,17 @@ + + +
+
+
+ +
diff --git a/test/ghostdriver-test/fixtures/common/mousePositionTracker.html b/test/ghostdriver-test/fixtures/common/mousePositionTracker.html new file mode 100644 index 00000000..39a31cda --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/mousePositionTracker.html @@ -0,0 +1,33 @@ + + + + + + + + + Div tracking mouse position. +
+
+ Move mouse here. +
+

+0, 0 +

+ + diff --git a/test/ghostdriver-test/fixtures/common/nestedElements.html b/test/ghostdriver-test/fixtures/common/nestedElements.html new file mode 100644 index 00000000..cf00083c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/nestedElements.html @@ -0,0 +1,155 @@ + + +

outside

+

outside

+
+

inside

+
+ + Here's a checkbox:
+ + + +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + +Span with class of one +
+ Find me + Also me + But not me +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/overflow-body.html b/test/ghostdriver-test/fixtures/common/overflow-body.html new file mode 100644 index 00000000..2d2264ce --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow-body.html @@ -0,0 +1,15 @@ + + + + The Visibility of Everyday Things + + + +

This image is copyright Simon Stewart and donated to the Selenium project for use in its test suites. +

+a nice beach + + + + + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_auto.html b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_auto.html new file mode 100644 index 00000000..cf8a6471 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_hidden.html b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_hidden.html new file mode 100644 index 00000000..96fd750a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_scroll.html b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_scroll.html new file mode 100644 index 00000000..6f1d90b6 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_auto_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_auto.html b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_auto.html new file mode 100644 index 00000000..24dd1928 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_hidden.html b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_hidden.html new file mode 100644 index 00000000..cae56657 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_scroll.html b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_scroll.html new file mode 100644 index 00000000..d4ffa397 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_hidden_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_auto.html b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_auto.html new file mode 100644 index 00000000..d425a2a8 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_hidden.html b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_hidden.html new file mode 100644 index 00000000..4a6ff595 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_scroll.html b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_scroll.html new file mode 100644 index 00000000..efa80742 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/overflow/x_scroll_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/test/ghostdriver-test/fixtures/common/pageWithOnBeforeUnloadMessage.html b/test/ghostdriver-test/fixtures/common/pageWithOnBeforeUnloadMessage.html new file mode 100644 index 00000000..cb59707e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/pageWithOnBeforeUnloadMessage.html @@ -0,0 +1,20 @@ + + + + + + Page with OnBeforeUnload handler + + +

Page with onbeforeunload event handler. Click here to navigate to another page.

+ + diff --git a/test/ghostdriver-test/fixtures/common/pageWithOnLoad.html b/test/ghostdriver-test/fixtures/common/pageWithOnLoad.html new file mode 100644 index 00000000..2c644ff9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/pageWithOnLoad.html @@ -0,0 +1,6 @@ + + + +

Page with onload event handler

+ + diff --git a/test/ghostdriver-test/fixtures/common/pageWithOnUnload.html b/test/ghostdriver-test/fixtures/common/pageWithOnUnload.html new file mode 100644 index 00000000..6070341e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/pageWithOnUnload.html @@ -0,0 +1,6 @@ + + + +

Page with onunload event handler

+ + diff --git a/test/ghostdriver-test/fixtures/common/plain.txt b/test/ghostdriver-test/fixtures/common/plain.txt new file mode 100644 index 00000000..8318c86b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/plain.txt @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/proxy/page1.html b/test/ghostdriver-test/fixtures/common/proxy/page1.html new file mode 100644 index 00000000..1810f1cd --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/proxy/page1.html @@ -0,0 +1,20 @@ + + + +Page 1 +

The next query param must be the URL for the next page to +link to. + diff --git a/test/ghostdriver-test/fixtures/common/proxy/page2.html b/test/ghostdriver-test/fixtures/common/proxy/page2.html new file mode 100644 index 00000000..d826f174 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/proxy/page2.html @@ -0,0 +1,24 @@ + + + +Page 2 +This page is a middle man for referrer tests. +This page will include a link to a "next" page if the next query +parameter, or the document.referrer is set. +

+ diff --git a/test/ghostdriver-test/fixtures/common/proxy/page3.html b/test/ghostdriver-test/fixtures/common/proxy/page3.html new file mode 100644 index 00000000..27048f72 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/proxy/page3.html @@ -0,0 +1,5 @@ + + + +Page 3 +

diff --git a/test/ghostdriver-test/fixtures/common/readOnlyPage.html b/test/ghostdriver-test/fixtures/common/readOnlyPage.html new file mode 100644 index 00000000..b3f0012b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/readOnlyPage.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + +

This is a contentEditable area
+ + + diff --git a/test/ghostdriver-test/fixtures/common/rectangles.html b/test/ghostdriver-test/fixtures/common/rectangles.html new file mode 100644 index 00000000..8ba23398 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/rectangles.html @@ -0,0 +1,40 @@ + + + + Rectangles + + + +
r1
+
r2
+
r3
+ + diff --git a/test/ghostdriver-test/fixtures/common/resultPage.html b/test/ghostdriver-test/fixtures/common/resultPage.html new file mode 100644 index 00000000..94f3e246 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/resultPage.html @@ -0,0 +1,25 @@ + + + We Arrive Here + + + +

Success!

+ +
+

List of stuff

+
    +
  1. Item 1
  2. +
  3. Item 2
  4. +
+
+
+

Almost empty

+
+ + + + + diff --git a/test/ghostdriver-test/fixtures/common/rich_text.html b/test/ghostdriver-test/fixtures/common/rich_text.html new file mode 100644 index 00000000..8c9a0736 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/rich_text.html @@ -0,0 +1,160 @@ + + + + + + +
+
+
+ + + + + +
+
IFRAME
+ +
+
frame.contentWindow.document.designMode: on
frame.contentWindow.document.body.contentEditable: false
+
+
DIV
+
+
+
+
div.ownerDocument.designMode: off
div.ownerDocument.body.contentEditable: false
div.contentEditable: true
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
type:[]
tagName:[]
id:[]
keyIdentifier:[]
keyLocation:[]
keyCode:[]
charCode:[]
which:[]
isTrusted:[]
---------------------
Modifiers
alt:[]
ctrl:[]
shift:[]
meta:[]
+
+ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/safari/frames_benchmark.html b/test/ghostdriver-test/fixtures/common/safari/frames_benchmark.html new file mode 100644 index 00000000..8a059255 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/safari/frames_benchmark.html @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen.css b/test/ghostdriver-test/fixtures/common/screen/screen.css new file mode 100644 index 00000000..81526185 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen.css @@ -0,0 +1,19 @@ +* { + margin: 0; +} +html, body, #output { + width: 100%; + height: 100%; +} +table { + border: 0px; + border-collapse: collapse; + border-spacing: 0px; + display: table; +} +table td { + padding: 0px; +} +.cell { + color: black; +} diff --git a/test/ghostdriver-test/fixtures/common/screen/screen.html b/test/ghostdriver-test/fixtures/common/screen/screen.html new file mode 100644 index 00000000..166665da --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen.js b/test/ghostdriver-test/fixtures/common/screen/screen.js new file mode 100644 index 00000000..1d168598 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen.js @@ -0,0 +1,7 @@ +function toColor(num) { + num >>>= 0; + var b = num & 0xFF, + g = (num & 0xFF00) >>> 8, + r = (num & 0xFF0000) >>> 16; + return "rgb(" + [r, g, b].join(",") + ")"; +} \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_frame1.html b/test/ghostdriver-test/fixtures/common/screen/screen_frame1.html new file mode 100644 index 00000000..d50c21db --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_frame1.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_frame2.html b/test/ghostdriver-test/fixtures/common/screen/screen_frame2.html new file mode 100644 index 00000000..b66cd700 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_frame2.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_frames.html b/test/ghostdriver-test/fixtures/common/screen/screen_frames.html new file mode 100644 index 00000000..46852dcf --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_frames.html @@ -0,0 +1,11 @@ + + + screen test + + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_iframes.html b/test/ghostdriver-test/fixtures/common/screen/screen_iframes.html new file mode 100644 index 00000000..ae3ea1e2 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_iframes.html @@ -0,0 +1,12 @@ + + +Screen test + + +
+ + + +
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_too_long.html b/test/ghostdriver-test/fixtures/common/screen/screen_too_long.html new file mode 100644 index 00000000..4d00f027 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_too_long.html @@ -0,0 +1,68 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_x_long.html b/test/ghostdriver-test/fixtures/common/screen/screen_x_long.html new file mode 100644 index 00000000..1a6a1002 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_x_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_x_too_long.html b/test/ghostdriver-test/fixtures/common/screen/screen_x_too_long.html new file mode 100644 index 00000000..3fee005d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_x_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_y_long.html b/test/ghostdriver-test/fixtures/common/screen/screen_y_long.html new file mode 100644 index 00000000..31733e07 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_y_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/screen/screen_y_too_long.html b/test/ghostdriver-test/fixtures/common/screen/screen_y_too_long.html new file mode 100644 index 00000000..dbef9361 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/screen/screen_y_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/scroll.html b/test/ghostdriver-test/fixtures/common/scroll.html new file mode 100644 index 00000000..cd5214f1 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scroll.html @@ -0,0 +1,27 @@ + + + + + +
+
    +
  • line1
  • +
  • line2
  • +
  • line3
  • +
  • line4
  • +
  • line5
  • +
  • line6
  • +
  • line7
  • +
  • line8
  • +
  • line9
  • +
+
+Clicked: +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scroll2.html b/test/ghostdriver-test/fixtures/common/scroll2.html new file mode 100644 index 00000000..0ea66d37 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scroll2.html @@ -0,0 +1,21 @@ + + + + +
    +
  • +
  • +
  • Text
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scroll3.html b/test/ghostdriver-test/fixtures/common/scroll3.html new file mode 100644 index 00000000..1aa17092 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scroll3.html @@ -0,0 +1,8 @@ + + +



























































































































































+ +



+ +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 +
























































































































































\ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/scroll4.html b/test/ghostdriver-test/fixtures/common/scroll4.html new file mode 100644 index 00000000..652a778e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scroll4.html @@ -0,0 +1,7 @@ + + +


































































































+ +


































































































+ + diff --git a/test/ghostdriver-test/fixtures/common/scroll5.html b/test/ghostdriver-test/fixtures/common/scroll5.html new file mode 100644 index 00000000..b345a8c3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scroll5.html @@ -0,0 +1,18 @@ + + + + + +
+
+
+
+
+Clicked: +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_200.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_200.html new file mode 100644 index 00000000..3eb3bf47 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_200.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a scrolling frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_2000.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_2000.html new file mode 100644 index 00000000..61ffe85d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_height_above_2000.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a tall frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame.html new file mode 100644 index 00000000..15301386 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html new file mode 100644 index 00000000..5781aeb9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_small_height.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_small_height.html new file mode 100644 index 00000000..047de0f1 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/frame_with_small_height.html @@ -0,0 +1,10 @@ + + + + Child frame + + +

This is a non-scrolling frame test

+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_double_overflow_auto.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_double_overflow_auto.html new file mode 100644 index 00000000..01b7c305 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_double_overflow_auto.html @@ -0,0 +1,19 @@ + + + + Page with overflow: auto + + + +
Placeholder
+
+ Click me! +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_frame_out_of_view.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_frame_out_of_view.html new file mode 100644 index 00000000..c536e41d --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames.html new file mode 100644 index 00000000..e5b76022 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html new file mode 100644 index 00000000..f79f7c84 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_non_scrolling_frame.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_non_scrolling_frame.html new file mode 100644 index 00000000..0a493fa5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_non_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame.html new file mode 100644 index 00000000..cb5d53a4 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame_out_of_view.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame_out_of_view.html new file mode 100644 index 00000000..5df1115c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_tall_frame.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_tall_frame.html new file mode 100644 index 00000000..b7cfaf5a --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_tall_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_y_overflow_auto.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_y_overflow_auto.html new file mode 100644 index 00000000..b5716e73 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/page_with_y_overflow_auto.html @@ -0,0 +1,14 @@ + + + + Page with overflow: auto + + +
+
Placeholder
+
+ Click me! +
+
+ + diff --git a/test/ghostdriver-test/fixtures/common/scrolling_tests/target_page.html b/test/ghostdriver-test/fixtures/common/scrolling_tests/target_page.html new file mode 100644 index 00000000..0457a822 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/scrolling_tests/target_page.html @@ -0,0 +1,9 @@ + + + +Clicked Successfully! + + +

Clicked Successfully!

+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/selectPage.html b/test/ghostdriver-test/fixtures/common/selectPage.html new file mode 100644 index 00000000..1c785ced --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/selectPage.html @@ -0,0 +1,42 @@ + + + + +Multiple Selection test page + + + + + + + + + + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/selectableItems.html b/test/ghostdriver-test/fixtures/common/selectableItems.html new file mode 100644 index 00000000..190b2ada --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/selectableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + +
+ +
    +
  1. Item 1
  2. +
  3. Item 2
  4. +
  5. Item 3
  6. +
  7. Item 4
  8. +
  9. Item 5
  10. +
  11. Item 6
  12. +
  13. Item 7
  14. +
+ +
+ +
+ +

Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

+ + + +
+

no info

+
+ + +
+ + diff --git a/test/ghostdriver-test/fixtures/common/sessionCookie.html b/test/ghostdriver-test/fixtures/common/sessionCookie.html new file mode 100644 index 00000000..0ada24ed --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/sessionCookie.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/test/ghostdriver-test/fixtures/common/sessionCookieDest.html b/test/ghostdriver-test/fixtures/common/sessionCookieDest.html new file mode 100644 index 00000000..f5e2ef2e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/sessionCookieDest.html @@ -0,0 +1,34 @@ + + + + + Session cookie destination + + + +This is the cookie destination page. + + diff --git a/test/ghostdriver-test/fixtures/common/simple.xml b/test/ghostdriver-test/fixtures/common/simple.xml new file mode 100644 index 00000000..01f4c87c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/simple.xml @@ -0,0 +1,5 @@ + + + baz + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/simpleTest.html b/test/ghostdriver-test/fixtures/common/simpleTest.html new file mode 100644 index 00000000..49bbc269 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/simpleTest.html @@ -0,0 +1,97 @@ + + + Hello WebDriver + + +

Heading

+ +

A single line of text

+ +
+

A div containing

+ More than one line of text
+ +
and block level elements
+
+ +An inline element + +

This line has lots + + of spaces. +

+ +

This line has a non-breaking space

+ +

This line has a   non-breaking space and spaces

+ +

These lines  
  have leading and trailing NBSPs  

+ +

This line has text within elements that are meant to be displayed + inline

+ +
+

before pre

+
   This section has a preformatted
+    text block    
+  split in four lines
+         
+

after pre

+
+ +

Some text

Some more text

+ +
Cheese

Some text

Some more text

and also

Brie
+ +
Hello, world
+ +
+ +
+ +
+

+ + +

+
+ + + + + +
Top level
+
+
Nested
+
+ + + + + +
beforeSpace afterSpace
+ + + + + +a link to an icon + +{a="b", c=1, d=true} +{a="\\b\\\"'\'"} + +  â€â€‚        ​‌â€â€¯âŸâ ã€€test  â€â€‚        ​‌â€â€¯âŸâ ã€€ + + + diff --git a/test/ghostdriver-test/fixtures/common/slowLoadingAlert.html b/test/ghostdriver-test/fixtures/common/slowLoadingAlert.html new file mode 100644 index 00000000..a6216e37 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/slowLoadingAlert.html @@ -0,0 +1,10 @@ + + + +slowLoadingAlert + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/slowLoadingResourcePage.html b/test/ghostdriver-test/fixtures/common/slowLoadingResourcePage.html new file mode 100644 index 00000000..e05f9546 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/slowLoadingResourcePage.html @@ -0,0 +1,12 @@ + + + This page loads something slowly + + +

Simulate the situation where a web-bug or analytics script takes waaay + too long to respond. Normally these things are loaded in an iframe, which is + what we're doing here.

+ + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/slow_loading_iframes.html b/test/ghostdriver-test/fixtures/common/slow_loading_iframes.html new file mode 100644 index 00000000..d007248e --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/slow_loading_iframes.html @@ -0,0 +1,14 @@ + + + + Page with slow loading iFrames + + + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/styledPage.html b/test/ghostdriver-test/fixtures/common/styledPage.html new file mode 100644 index 00000000..30810f09 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/styledPage.html @@ -0,0 +1,28 @@ + + + + Styled Page + + + + +
+ +
+ + +
+ +
+ +
Content
+ + + + + + diff --git a/test/ghostdriver-test/fixtures/common/svgPiechart.xhtml b/test/ghostdriver-test/fixtures/common/svgPiechart.xhtml new file mode 100644 index 00000000..bf060fde --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/svgPiechart.xhtml @@ -0,0 +1,81 @@ + + + + + Pie Chart Test + + + +
+ Some text for the chart. +
+
Nothing.
+
+ + + + + Test Chart + + + Apple + + Orange + + Banana + + Orange + + + + + + + + Example RotateScale - Rotate and scale transforms + + + + + + + + + + + + + + ABC (rotate) + + + + + + + + + + + + ABC (scale) + + + + +
WOrange
+
+
WOrange
+ + diff --git a/test/ghostdriver-test/fixtures/common/svgTest.svg b/test/ghostdriver-test/fixtures/common/svgTest.svg new file mode 100644 index 00000000..c6cc2839 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/svgTest.svg @@ -0,0 +1,4 @@ + + + + diff --git a/test/ghostdriver-test/fixtures/common/tables.html b/test/ghostdriver-test/fixtures/common/tables.html new file mode 100644 index 00000000..a2bc957b --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/tables.html @@ -0,0 +1,36 @@ + + + + Here be tables + + + + + + + + + +
HelloWorld(Cheese!)
+ + + + + +
some text +
some more text
+
+ + + + + + + + + +
Heading
Data 1Data 2
+ + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/transformable.xml b/test/ghostdriver-test/fixtures/common/transformable.xml new file mode 100644 index 00000000..0b7e7fd5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/transformable.xml @@ -0,0 +1,11 @@ + + + ]> + + +

Click the button.

+ + Go to another page + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/transformable.xsl b/test/ghostdriver-test/fixtures/common/transformable.xsl new file mode 100644 index 00000000..53db9fde --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/transformable.xsl @@ -0,0 +1,37 @@ + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/underscore.html b/test/ghostdriver-test/fixtures/common/underscore.html new file mode 100644 index 00000000..904a4441 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/underscore.html @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/unicode_ltr.html b/test/ghostdriver-test/fixtures/common/unicode_ltr.html new file mode 100644 index 00000000..245acc74 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/unicode_ltr.html @@ -0,0 +1,8 @@ + + + + + +
‎Some notes‎
+ + diff --git a/test/ghostdriver-test/fixtures/common/upload.html b/test/ghostdriver-test/fixtures/common/upload.html new file mode 100644 index 00000000..aca398ab --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/upload.html @@ -0,0 +1,45 @@ + + + + Upload Form + + + +
+
+ Enter a file to upload: +
+
+
+ + +
+ + diff --git a/test/ghostdriver-test/fixtures/common/userDefinedProperty.html b/test/ghostdriver-test/fixtures/common/userDefinedProperty.html new file mode 100644 index 00000000..2453e692 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/userDefinedProperty.html @@ -0,0 +1,8 @@ + + +
+ + + diff --git a/test/ghostdriver-test/fixtures/common/veryLargeCanvas.html b/test/ghostdriver-test/fixtures/common/veryLargeCanvas.html new file mode 100644 index 00000000..54a2aba4 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/veryLargeCanvas.html @@ -0,0 +1,81 @@ + + + + Rectangles + + + + +
+
First Target
+
Second Target
+
Third Target
+
Fourth Target
+
Not a Target
+
Not a Target
+ + diff --git a/test/ghostdriver-test/fixtures/common/visibility-css.html b/test/ghostdriver-test/fixtures/common/visibility-css.html new file mode 100644 index 00000000..80cc649c --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/visibility-css.html @@ -0,0 +1,21 @@ + + + + +Visibility test via CSS + +
+

Hello world. I like cheese.

+
+ + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/win32frameset.html b/test/ghostdriver-test/fixtures/common/win32frameset.html new file mode 100644 index 00000000..108b80f8 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/win32frameset.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/common/window_switching_tests/page_with_frame.html b/test/ghostdriver-test/fixtures/common/window_switching_tests/page_with_frame.html new file mode 100644 index 00000000..b94733b5 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/window_switching_tests/page_with_frame.html @@ -0,0 +1,12 @@ + + + + Test page for WindowSwitchingTest.testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow + + +

Open new window

+
+ +
+ + diff --git a/test/ghostdriver-test/fixtures/common/window_switching_tests/simple_page.html b/test/ghostdriver-test/fixtures/common/window_switching_tests/simple_page.html new file mode 100644 index 00000000..52c163cb --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/window_switching_tests/simple_page.html @@ -0,0 +1,9 @@ + + + + Simple Page + + +
Simple page with simple test.
+ + diff --git a/test/ghostdriver-test/fixtures/common/xhtmlFormPage.xhtml b/test/ghostdriver-test/fixtures/common/xhtmlFormPage.xhtml new file mode 100644 index 00000000..aca53d34 --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/xhtmlFormPage.xhtml @@ -0,0 +1,17 @@ + + + + XHTML + + + +
+ + +
+ +

Here is some content that should not be in the previous p tag + + + diff --git a/test/ghostdriver-test/fixtures/common/xhtmlTest.html b/test/ghostdriver-test/fixtures/common/xhtmlTest.html new file mode 100644 index 00000000..d2f3a5da --- /dev/null +++ b/test/ghostdriver-test/fixtures/common/xhtmlTest.html @@ -0,0 +1,76 @@ + + + + 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/test/ghostdriver-test/fixtures/right_frame/0.html b/test/ghostdriver-test/fixtures/right_frame/0.html new file mode 100644 index 00000000..e6fa019a --- /dev/null +++ b/test/ghostdriver-test/fixtures/right_frame/0.html @@ -0,0 +1,38911 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/right_frame/1.html b/test/ghostdriver-test/fixtures/right_frame/1.html new file mode 100644 index 00000000..39b65dd9 --- /dev/null +++ b/test/ghostdriver-test/fixtures/right_frame/1.html @@ -0,0 +1,51 @@ + +WYSIWYG Editor Input Template + + + + + + + + + + + + +
  • foo.
  • bar
\ No newline at end of file diff --git a/test/ghostdriver-test/fixtures/right_frame/outside.html b/test/ghostdriver-test/fixtures/right_frame/outside.html new file mode 100644 index 00000000..b240224d --- /dev/null +++ b/test/ghostdriver-test/fixtures/right_frame/outside.html @@ -0,0 +1,414 @@ + + + Editing testDotAtEndDoesNotDelete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+ +
+ + +
+
+
+
+ + + + +
+ +
+
+ +
+ + + + +
+ +
+
+
 
 
+ + + + + + + + + + + + + + + +
+
+
+
+ +
+ + +
+ + + + +
+
+ + + +
+
+
+

Document information

+

+ +

XWiki Syntax Help

Help on the XWiki Syntax

+
+ + +
+
+
+
+
+
This wiki is licensed under a Creative Commons 2.0 license
+
XWiki Enterprise 5.1-SNAPSHOT - Documentation
+
+
+ +
+
diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/1 b/test/ghostdriver-test/fixtures/testcase-issue_240/1 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/2 b/test/ghostdriver-test/fixtures/testcase-issue_240/2 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/3 b/test/ghostdriver-test/fixtures/testcase-issue_240/3 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/4 b/test/ghostdriver-test/fixtures/testcase-issue_240/4 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/5 b/test/ghostdriver-test/fixtures/testcase-issue_240/5 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/6 b/test/ghostdriver-test/fixtures/testcase-issue_240/6 new file mode 100644 index 00000000..e69de29b diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/test.html b/test/ghostdriver-test/fixtures/testcase-issue_240/test.html new file mode 100644 index 00000000..e5ebdb72 --- /dev/null +++ b/test/ghostdriver-test/fixtures/testcase-issue_240/test.html @@ -0,0 +1,97 @@ + + + + test + + + + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + 1 + 2 + 3 + 4 + 5 + 6 + + + + + diff --git a/test/ghostdriver-test/fixtures/testcase-issue_240/wb.rb b/test/ghostdriver-test/fixtures/testcase-issue_240/wb.rb new file mode 100644 index 00000000..d51106a3 --- /dev/null +++ b/test/ghostdriver-test/fixtures/testcase-issue_240/wb.rb @@ -0,0 +1,62 @@ +require 'json' +require 'shellwords' + +def c (method, url, data) + ret = `curl -s -X #{method} http://localhost:10000/#{url} --data-binary #{data.to_json.shellescape}` + return JSON.parse ret rescue ret +end + +def g (url, data={}) + c "GET", url, data +end + +def o (url, data) + c "POST", url, data +end + +def a (session, action, data = {}) + o "session/#{session}/#{action}", data +end + +def exec (session, js) + a(session, "execute", { script: "return #{js}", args: [] })["value"] +end + +def css (session, selector) + a(session, "elements", { using: 'css selector', value: selector })["value"].map { |x| x["ELEMENT"] } +end + +def click (session, element) + a(session, "element/#{element}/click") +end + +session_data = { + desiredCapabilities: { + browserName: "phantomjs", + platform: "ANY", + javascriptEnabled: true, + cssSelectorsEnabled: true, + takesScreenshot: true, + nativeEvents: false, + rotatable: false + } +} + +sessions = g("sessions", {})["value"] +if sessions.empty? + o("session", session_data) + sleep 0.5 +end +session = g("sessions", {})["value"][0]["id"] + +puts "Got session: #{session}" +a session, "url", { url: "http://localhost:8000/test.html" } +print "Going to do it now..." + + +css(session, "a").each do |i| + click session, i + # puts "Clicked on #{i}" +end + +puts exec session, "results" diff --git a/test/ghostdriver-test/java/build.gradle b/test/ghostdriver-test/java/build.gradle new file mode 100644 index 00000000..8adc989d --- /dev/null +++ b/test/ghostdriver-test/java/build.gradle @@ -0,0 +1,42 @@ +apply plugin: "java" +apply plugin: "idea" +apply plugin: "eclipse" + +task wrapper(type: Wrapper) { + gradleVersion = "1.10" + jarFile = "gradle/gradle-wrapper.jar" +} + +repositories { + mavenCentral() +} + +ext.commonsFileUploadVersion = "1.3" +ext.seleniumVersion = "2.39.0" +ext.junitVersion = "4.11" +ext.jettyVersion = "6.1.21" +ext.jsr305Version = "2.0.1" +ext.phantomjsdriverVersion = "1.1.0" + +dependencies { + ["selenium-java", "selenium-remote-driver", "selenium-server"].each { + testCompile "org.seleniumhq.selenium:$it:$seleniumVersion" + } + testCompile "com.google.code.findbugs:jsr305:$jsr305Version" + testCompile "junit:junit-dep:$junitVersion" + testCompile "org.mortbay.jetty:jetty:$jettyVersion" + testCompile "commons-fileupload:commons-fileupload:$commonsFileUploadVersion" + testCompile "com.github.detro.ghostdriver:phantomjsdriver:$phantomjsdriverVersion" +} + +tasks.withType(JavaExec) { + classpath = configurations.compile + sourceSets.test.output + args project.hasProperty("args") ? project.args.split("\\s") : [] +} + +test { + // Listening to test execution events + beforeTest { descriptor -> + logger.lifecycle("Running " + descriptor) + } +} diff --git a/test/ghostdriver-test/java/gradle/gradle-wrapper.jar b/test/ghostdriver-test/java/gradle/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..5838598129719e795cc5633f411468bdec311016 GIT binary patch literal 50557 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 literal 0 HcmV?d00001 diff --git a/test/ghostdriver-test/java/gradle/gradle-wrapper.properties b/test/ghostdriver-test/java/gradle/gradle-wrapper.properties new file mode 100644 index 00000000..dc3ff0dc --- /dev/null +++ b/test/ghostdriver-test/java/gradle/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Dec 30 09:41:35 GMT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip diff --git a/test/ghostdriver-test/java/gradlew b/test/ghostdriver-test/java/gradlew new file mode 100755 index 00000000..9e810c47 --- /dev/null +++ b/test/ghostdriver-test/java/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/test/ghostdriver-test/java/gradlew.bat b/test/ghostdriver-test/java/gradlew.bat new file mode 100644 index 00000000..661508d9 --- /dev/null +++ b/test/ghostdriver-test/java/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/test/ghostdriver-test/java/settings.gradle b/test/ghostdriver-test/java/settings.gradle new file mode 100644 index 00000000..4fd8a728 --- /dev/null +++ b/test/ghostdriver-test/java/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "ghostdriver-test" diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTest.java new file mode 100644 index 00000000..76f9f456 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTest.java @@ -0,0 +1,163 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.phantomjs.PhantomJSDriver; +import org.openqa.selenium.phantomjs.PhantomJSDriverService; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.RemoteWebDriver; + +import java.io.FileReader; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Properties; + +/** + * Tests base class. + * Takes care of initialising the Remote WebDriver + */ +public abstract class BaseTest { + private WebDriver mDriver = null; + private boolean mAutoQuitDriver = true; + + private static final String CONFIG_FILE = "../config.ini"; + private static final String DRIVER_FIREFOX = "firefox"; + private static final String DRIVER_CHROME = "chrome"; + private static final String DRIVER_PHANTOMJS = "phantomjs"; + + protected static Properties sConfig; + protected static DesiredCapabilities sCaps; + + private static boolean isUrl(String urlString) { + try { + new URL(urlString); + return true; + } catch (MalformedURLException mue) { + return false; + } + } + + @BeforeClass + public static void configure() throws IOException { + // Read config file + sConfig = new Properties(); + sConfig.load(new FileReader(CONFIG_FILE)); + + // Prepare capabilities + sCaps = new DesiredCapabilities(); + sCaps.setJavascriptEnabled(true); + sCaps.setCapability("takesScreenshot", false); + + String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS); + + // Fetch PhantomJS-specific configuration parameters + if (driver.equals(DRIVER_PHANTOMJS)) { + // "phantomjs_exec_path" + if (sConfig.getProperty("phantomjs_exec_path") != null) { + sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, sConfig.getProperty("phantomjs_exec_path")); + } else { + throw new IOException(String.format("Property '%s' not set!", PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY)); + } + // "phantomjs_driver_path" + if (sConfig.getProperty("phantomjs_driver_path") != null) { + System.out.println("Test will use an external GhostDriver"); + sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_PATH_PROPERTY, sConfig.getProperty("phantomjs_driver_path")); + } else { + System.out.println("Test will use PhantomJS internal GhostDriver"); + } + } + + // Disable "web-security", enable all possible "ssl-protocols" and "ignore-ssl-errors" for PhantomJSDriver +// sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, new String[] { +// "--web-security=false", +// "--ssl-protocol=any", +// "--ignore-ssl-errors=true" +// }); + ArrayList cliArgsCap = new ArrayList(); + cliArgsCap.add("--web-security=false"); + cliArgsCap.add("--ssl-protocol=any"); + cliArgsCap.add("--ignore-ssl-errors=true"); + sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap); + + // Control LogLevel for GhostDriver, via CLI arguments + sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_CLI_ARGS, new String[] { + "--logLevel=" + (sConfig.getProperty("phantomjs_driver_loglevel") != null ? sConfig.getProperty("phantomjs_driver_loglevel") : "INFO") + }); + } + + @Before + public void prepareDriver() throws Exception + { + // Which driver to use? (default "phantomjs") + String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS); + + // Start appropriate Driver + if (isUrl(driver)) { + sCaps.setBrowserName("phantomjs"); + mDriver = new RemoteWebDriver(new URL(driver), sCaps); + } else if (driver.equals(DRIVER_FIREFOX)) { + mDriver = new FirefoxDriver(sCaps); + } else if (driver.equals(DRIVER_CHROME)) { + mDriver = new ChromeDriver(sCaps); + } else if (driver.equals(DRIVER_PHANTOMJS)) { + mDriver = new PhantomJSDriver(sCaps); + } + } + + protected WebDriver getDriver() { + return mDriver; + } + + protected void disableAutoQuitDriver() { + mAutoQuitDriver = false; + } + + protected void enableAutoQuitDriver() { + mAutoQuitDriver = true; + } + + protected boolean isAutoQuitDriverEnabled() { + return mAutoQuitDriver; + } + + @After + public void quitDriver() { + if (mAutoQuitDriver && mDriver != null) { + mDriver.quit(); + mDriver = null; + } + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTestWithServer.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTestWithServer.java new file mode 100644 index 00000000..37eded56 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/BaseTestWithServer.java @@ -0,0 +1,47 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.CallbackHttpServer; +import org.junit.After; +import org.junit.Before; + +abstract public class BaseTestWithServer extends BaseTest { + protected CallbackHttpServer server; + + @Before + public void startServer() throws Exception { + server = new CallbackHttpServer(); + server.start(); + } + + @After + public void stopServer() throws Exception { + server.stop(); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/CookieTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/CookieTest.java new file mode 100644 index 00000000..fa4ab34a --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/CookieTest.java @@ -0,0 +1,317 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.EmptyPageHttpRequestCallback; +import ghostdriver.server.HttpRequestCallback; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.Cookie; +import org.openqa.selenium.InvalidCookieDomainException; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; + +import static org.junit.Assert.*; + +public class CookieTest extends BaseTestWithServer { + private WebDriver driver; + + private final static HttpRequestCallback COOKIE_SETTING_CALLBACK = new EmptyPageHttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + super.call(req, res); + javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("test", "test"); + cookie.setDomain(".localhost"); + cookie.setMaxAge(360); + + res.addCookie(cookie); + + cookie = new javax.servlet.http.Cookie("test2", "test2"); + cookie.setDomain(".localhost"); + res.addCookie(cookie); + } + }; + + private final static HttpRequestCallback EMPTY_CALLBACK = new EmptyPageHttpRequestCallback(); + + @Before + public void setup() { + driver = getDriver(); + } + + @After + public void cleanUp() { + driver.manage().deleteAllCookies(); + } + + private void goToPage(String path) { + driver.get(server.getBaseUrl() + path); + } + + private void goToPage() { + goToPage(""); + } + + private Cookie[] getCookies() { + return driver.manage().getCookies().toArray(new Cookie[]{}); + } + + @Test + public void gettingAllCookies() { + server.setHttpHandler("GET", COOKIE_SETTING_CALLBACK); + goToPage(); + Cookie[] cookies = getCookies(); + + assertEquals(2, cookies.length); + assertEquals("test", cookies[0].getName()); + assertEquals("test", cookies[0].getValue()); + assertEquals(".localhost", cookies[0].getDomain()); + assertEquals("/", cookies[0].getPath()); + assertTrue(cookies[0].getExpiry() != null); + assertEquals(false, cookies[0].isSecure()); + assertEquals("test2", cookies[1].getName()); + assertEquals("test2", cookies[1].getValue()); + assertEquals(".localhost", cookies[1].getDomain()); + assertEquals("/", cookies[1].getPath()); + assertEquals(false, cookies[1].isSecure()); + assertTrue(cookies[1].getExpiry() == null); + } + + @Test + public void gettingAllCookiesOnANonCookieSettingPage() { + server.setHttpHandler("GET", EMPTY_CALLBACK); + goToPage(); + assertEquals(0, getCookies().length); + } + + @Test + public void deletingAllCookies() { + server.setHttpHandler("GET", COOKIE_SETTING_CALLBACK); + goToPage(); + driver.manage().deleteAllCookies(); + assertEquals(0, getCookies().length); + } + + @Test + public void deletingOneCookie() { + server.setHttpHandler("GET", COOKIE_SETTING_CALLBACK); + goToPage(); + + driver.manage().deleteCookieNamed("test"); + + Cookie[] cookies = getCookies(); + + assertEquals(1, cookies.length); + assertEquals("test2", cookies[0].getName()); + } + + @Test + public void addingACookie() { + server.setHttpHandler("GET", EMPTY_CALLBACK); + goToPage(); + + driver.manage().addCookie(new Cookie("newCookie", "newValue")); + + Cookie[] cookies = getCookies(); + assertEquals(1, cookies.length); + assertEquals("newCookie", cookies[0].getName()); + assertEquals("newValue", cookies[0].getValue()); + assertEquals("localhost", cookies[0].getDomain()); + assertEquals("/", cookies[0].getPath()); + assertEquals(false, cookies[0].isSecure()); + } + + @Test + public void modifyingACookie() { + server.setHttpHandler("GET", COOKIE_SETTING_CALLBACK); + goToPage(); + + driver.manage().addCookie(new Cookie("test", "newValue", "localhost", "/", null, false)); + + Cookie[] cookies = getCookies(); + assertEquals(2, cookies.length); + assertEquals("test", cookies[0].getName()); + assertEquals("newValue", cookies[0].getValue()); + assertEquals(".localhost", cookies[0].getDomain()); + assertEquals("/", cookies[0].getPath()); + assertEquals(false, cookies[0].isSecure()); + + assertEquals("test2", cookies[1].getName()); + assertEquals("test2", cookies[1].getValue()); + assertEquals(".localhost", cookies[1].getDomain()); + assertEquals("/", cookies[1].getPath()); + assertEquals(false, cookies[1].isSecure()); + } + + @Test + public void shouldRetainCookieInfo() { + server.setHttpHandler("GET", EMPTY_CALLBACK); + goToPage(); + + // Added cookie (in a sub-path - allowed) + Cookie addedCookie = + new Cookie.Builder("fish", "cod") + .expiresOn(new Date(System.currentTimeMillis() + 100 * 1000)) //< now + 100sec + .path("/404") + .domain("localhost") + .build(); + driver.manage().addCookie(addedCookie); + + // Search cookie on the root-path and fail to find it + Cookie retrieved = driver.manage().getCookieNamed("fish"); + assertNull(retrieved); + + // Go to the "/404" sub-path (to find the cookie) + goToPage("404"); + retrieved = driver.manage().getCookieNamed("fish"); + assertNotNull(retrieved); + // Check that it all matches + assertEquals(addedCookie.getName(), retrieved.getName()); + assertEquals(addedCookie.getValue(), retrieved.getValue()); + assertEquals(addedCookie.getExpiry(), retrieved.getExpiry()); + assertEquals(addedCookie.isSecure(), retrieved.isSecure()); + assertEquals(addedCookie.getPath(), retrieved.getPath()); + assertTrue(retrieved.getDomain().contains(addedCookie.getDomain())); + } + + @Test(expected = InvalidCookieDomainException.class) + public void shouldNotAllowToCreateCookieOnDifferentDomain() { + goToPage(); + + // Added cookie (in a sub-path) + Cookie addedCookie = new Cookie.Builder("fish", "cod") + .expiresOn(new Date(System.currentTimeMillis() + 100 * 1000)) //< now + 100sec + .path("/404") + .domain("github.com") + .build(); + driver.manage().addCookie(addedCookie); + } + + @Test + public void shouldAllowToDeleteCookiesEvenIfNotSet() { + WebDriver d = getDriver(); + d.get("https://github.com/"); + + // Clear all cookies + assertTrue(d.manage().getCookies().size() > 0); + d.manage().deleteAllCookies(); + assertEquals(d.manage().getCookies().size(), 0); + + // All cookies deleted, call deleteAllCookies again. Should be a no-op. + d.manage().deleteAllCookies(); + d.manage().deleteCookieNamed("non_existing_cookie"); + assertEquals(d.manage().getCookies().size(), 0); + } + + @Test + public void shouldAllowToSetCookieThatIsAlreadyExpired() { + WebDriver d = getDriver(); + d.get("https://github.com/"); + + // Clear all cookies + assertTrue(d.manage().getCookies().size() > 0); + d.manage().deleteAllCookies(); + assertEquals(d.manage().getCookies().size(), 0); + + // Added cookie that expires in the past + Cookie addedCookie = new Cookie.Builder("expired", "yes") + .expiresOn(new Date(System.currentTimeMillis() - 1000)) //< now - 1 second + .build(); + d.manage().addCookie(addedCookie); + + Cookie cookie = d.manage().getCookieNamed("expired"); + assertNull(cookie); + } + + @Test(expected = Exception.class) + public void shouldThrowExceptionIfAddingCookieBeforeLoadingAnyUrl() { + // NOTE: At the time of writing, this test doesn't pass with FirefoxDriver. + // ChromeDriver is fine instead. + String xval = "123456789101112"; //< detro: I buy you a beer if you guess what am I quoting here + WebDriver d = getDriver(); + + // Set cookie, without opening any page: should throw an exception + d.manage().addCookie(new Cookie("x", xval)); + } + + @Test + public void shouldBeAbleToCreateCookieViaJavascriptOnGoogle() { + String ckey = "cookiekey"; + String cval = "cookieval"; + + WebDriver d = getDriver(); + d.get("http://www.google.com"); + JavascriptExecutor js = (JavascriptExecutor) d; + + // Of course, no cookie yet(!) + Cookie c = d.manage().getCookieNamed(ckey); + assertNull(c); + + // Attempt to create cookie on multiple Google domains + js.executeScript("javascript:(" + + "function() {" + + " cook = document.cookie;" + + " begin = cook.indexOf('"+ckey+"=');" + + " var val;" + + " if (begin !== -1) {" + + " var end = cook.indexOf(\";\",begin);" + + " if (end === -1)" + + " end=cook.length;" + + " val=cook.substring(begin+11,end);" + + " }" + + " val = ['"+cval+"'];" + + " if (val) {" + + " var d=Array('com','co.jp','ca','fr','de','co.uk','it','es','com.br');" + + " for (var i = 0; i < d.length; i++) {" + + " document.cookie = '"+ckey+"='+val+';path=/;domain=.google.'+d[i]+'; ';" + + " }" + + " }" + + "})();"); + c = d.manage().getCookieNamed(ckey); + assertNotNull(c); + assertEquals(cval, c.getValue()); + + // Set cookie as empty + js.executeScript("javascript:(" + + "function() {" + + " var d = Array('com','co.jp','ca','fr','de','co.uk','it','cn','es','com.br');" + + " for(var i = 0; i < d.length; i++) {" + + " document.cookie='"+ckey+"=;path=/;domain=.google.'+d[i]+'; ';" + + " }" + + "})();"); + c = d.manage().getCookieNamed(ckey); + assertNotNull(c); + assertEquals("", c.getValue()); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/DriverBasicTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/DriverBasicTest.java new file mode 100644 index 00000000..1190b793 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/DriverBasicTest.java @@ -0,0 +1,37 @@ +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.WebDriver; + +public class DriverBasicTest extends BaseTest { + @Test + public void useDriverButDontQuit() { + WebDriver d = getDriver(); + disableAutoQuitDriver(); + + d.get("http://www.google.com/"); + d.quit(); + } + +// @Test +// public void shouldSurviveExecutingManyTimesTheSameCommand() { +// WebDriver d = getDriver(); +// d.get("http://www.google.com"); +// for (int j = 0; j < 100; j++) { +// try { +// d.findElement(By.linkText(org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(4))).isDisplayed(); +// } catch (NoSuchElementException nsee) { +// // swallow exceptions: we don't care about the result +// } +// } +// } +// +// @Test +// public void shouldSurviveExecutingManyTimesTheSameTest() throws Exception { +// for (int i = 0; i < 100; ++i) { +// prepareDriver(); +// shouldSurviveExecutingManyTimesTheSameCommand(); +// quitDriver(); +// } +// } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementFindingTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementFindingTest.java new file mode 100644 index 00000000..fca0fb76 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementFindingTest.java @@ -0,0 +1,261 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.*; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.*; + +public class ElementFindingTest extends BaseTestWithServer { + @Test + public void findChildElement() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("
" + + "" + + "" + + "
"); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + WebElement parent = d.findElement(By.id("y-masthead")); + + assertNotNull(parent.findElement(By.name("t"))); + } + + @Test + public void findChildElements() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("
" + + "" + + "" + + "
"); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + WebElement parent = d.findElement(By.id("y-masthead")); + + List children = parent.findElements(By.tagName("input")); + assertEquals(2, children.size()); + } + + @Test + public void findMultipleElements() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("
" + + "" + + "" + + "" + + "
"); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + assertEquals(3, d.findElements(By.tagName("input")).size()); + } + + @Test + public void findNoElementsMeetingCriteria() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + List els = d.findElements(By.name("noElementWithThisName")); + + assertEquals(0, els.size()); + } + + @Test + public void findNoChildElementsMeetingCriteria() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement parent = d.findElement(By.name("q")); + + List children = parent.findElements(By.tagName("input")); + + assertEquals(0, children.size()); + } + + @Test + public void findActiveElement() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement inputField = d.findElement(By.cssSelector("input[name='q']")); + WebElement active = d.switchTo().activeElement(); + + assertEquals(inputField.getTagName(), active.getTagName()); + assertEquals(inputField.getLocation(), active.getLocation()); + assertEquals(inputField.hashCode(), active.hashCode()); + assertEquals(inputField.getText(), active.getText()); + assertTrue(inputField.equals(active)); + } + + @Test(expected = NoSuchElementException.class) + public void failToFindNonExistentElement() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement inputField = d.findElement(By.cssSelector("input[name='idontexist']")); + } + + @Test(expected = InvalidSelectorException.class) + public void failFindElementForInvalidXPathLocator() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement inputField = d.findElement(By.xpath("this][isnot][valid")); + } + + @Test(expected = InvalidSelectorException.class) + public void failFindElementsForInvalidXPathLocator() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + List inputField = d.findElements(By.xpath("this][isnot][valid")); + } + + @Test + public void findElementWithImplicitWait() { + WebDriver d = getDriver(); + + d.get("about:blank"); + String injectLink = "document.body.innerHTML = \"add\""; + ((JavascriptExecutor)d).executeScript(injectLink); + WebElement add = d.findElement(By.id("add")); + + // DO NOT WAIT when looking for an element + d.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); + + // Add element + add.click(); + // Check element is not there yet + try { + d.findElement(By.id("testing1")); + throw new RuntimeException("expected NoSuchElementException"); + } catch (NoSuchElementException nse) { /* nothing to do */ } + + // DO WAIT 1 SECOND before giving up while looking for an element + d.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); + // Add element + add.click(); + // Check element is there + assertNotNull(d.findElement(By.id("testing2"))); + + // DO WAIT 0.5 SECONDS before giving up while looking for an element + d.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS); + // Add element + add.click(); + + // Check element is not there yet + try { + d.findElement(By.id("testing3")); + throw new RuntimeException("expected NoSuchElementException"); + } catch (NoSuchElementException nse) { /* nothing to do */ } + } + + @Test + public void findElementsWithImplicitWait() { + WebDriver d = getDriver(); + + d.get("about:blank"); + String injectLink = "document.body.innerHTML = \"add\""; + ((JavascriptExecutor)d).executeScript(injectLink); + WebElement add = d.findElement(By.id("add")); + + // DO NOT WAIT while looking for an element + d.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); + // Add element + add.click(); + // Check element is not there yet + assertEquals(0, d.findElements(By.id("testing1")).size()); + + // DO WAIT 3 SEC when looking for an element + d.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS); + // Add element + add.click(); + // Check element is there + assert(d.findElements(By.tagName("span")).size() >= 1 && d.findElements(By.tagName("span")).size() <= 2); + } + + @Test + public void findElementViaXpathLocator() { + // Define HTTP response for test + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + ServletOutputStream out = res.getOutputStream(); + out.println("" + + "" + + ""); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + WebElement loginButton = d.findElement(By.xpath("//button[contains(@class, 'login')]")); + assertNotNull(loginButton); + assertTrue(loginButton.getText().toLowerCase().contains("login")); + assertEquals("button", loginButton.getTagName().toLowerCase()); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementJQueryEventsTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementJQueryEventsTest.java new file mode 100644 index 00000000..23af93cf --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementJQueryEventsTest.java @@ -0,0 +1,107 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; + +import static org.junit.Assert.assertTrue; + +@RunWith(value = Parameterized.class) +public class ElementJQueryEventsTest extends BaseTestWithServer { + + @Parameters(name = "jQuery Version: {0}") + public static Iterable data() { + return Arrays.asList(new Object[][]{ + {"2.0.3"}, {"2.0.2"}, {"2.0.1"}, {"2.0.0"}, + {"1.10.2"}, {"1.10.1"}, {"1.10.0"}, + {"1.9.1"}, {"1.9.0"}, + {"1.8.3"}, {"1.8.2"}, {"1.8.1"}, {"1.8.0"}, + {"1.7.2"}, //{"1.7.1"}, {"1.7.0"}, + {"1.6.4"}, //{"1.6.3"}, {"1.6.2"}, {"1.6.1"}, {"1.6.0"}, + {"1.5.2"}, //{"1.5.1"}, {"1.5.0"}, + {"1.4.4"}, //{"1.4.3"}, {"1.4.2"}, {"1.4.1"}, {"1.4.0"}, + {"1.3.2"}, //{"1.3.1"}, {"1.3.0"}, + {"1.2.6"}, //{"1.2.3"} + }); + } + + private String mJqueryVersion; + + public ElementJQueryEventsTest(String jQueryVersion) { + mJqueryVersion = jQueryVersion; + } + + @Test + public void shouldBeAbleToClickAndEventsBubbleUpUsingJquery() { + final String buttonId = "clickme"; + + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println( + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + " click me\n" + + "\n" + + ""); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Click on the link inside the page + d.findElement(By.id(buttonId)).click(); + + // Check element was clicked as expected + assertTrue((Boolean)((JavascriptExecutor)d).executeScript("return clicked;")); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementMethodsTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementMethodsTest.java new file mode 100644 index 00000000..cbb8cb94 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementMethodsTest.java @@ -0,0 +1,264 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ElementMethodsTest extends BaseTestWithServer { + @Test + public void checkDisplayedOnGoogleSearchBox() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement el = d.findElement(By.cssSelector("input[name*='q']")); + + assertTrue(el.isDisplayed()); + + el = d.findElement(By.cssSelector("input[type='hidden']")); + + assertFalse(el.isDisplayed()); + } + + @Test + public void checkEnabledOnGoogleSearchBox() { + // TODO: Find a sample site that has hidden elements and use it to + // verify behavior of enabled and disabled elements. + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement el = d.findElement(By.cssSelector("input[name*='q']")); + + assertTrue(el.isEnabled()); + } + + @Test + public void checkClickOnAHREFCausesPageLoad() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement link = d.findElement(By.cssSelector("a[href=\"/intl/en/ads/\"]")); + link.click(); + + assertTrue(d.getTitle().contains("Ads")); + } + + @Test + public void checkClickOnINPUTSUBMITCausesPageLoad() { + WebDriver d = getDriver(); + + d.get("http://www.duckduckgo.com"); + WebElement textInput = d.findElement(By.cssSelector("#search_form_input_homepage")); + WebElement submitInput = d.findElement(By.cssSelector("#search_button_homepage")); + + + assertFalse(d.getTitle().contains("clicking")); + textInput.click(); + assertFalse(d.getTitle().contains("clicking")); + textInput.sendKeys("clicking"); + assertFalse(d.getTitle().contains("clicking")); + + submitInput.click(); + assertTrue(d.getTitle().contains("clicking")); + } + + @Test + public void SubmittingFormShouldFireOnSubmitForThatForm() { + WebDriver d = getDriver(); + + d.get(server.getBaseUrl() + "/common/javascriptPage.html"); + + WebElement formElement = d.findElement(By.id("submitListeningForm")); + formElement.submit(); + + WebDriverWait wait = new WebDriverWait(d, 30); + wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("result"), "form-onsubmit")); + + WebElement result = d.findElement(By.id("result")); + String text = result.getText(); + boolean conditionMet = text.contains("form-onsubmit"); + + assertTrue(conditionMet); + } + + @Test + public void shouldWaitForPossiblePageLoadOnlyWhenClickingOnSomeElement() { + WebDriver d = getDriver(); + + d.get("http://duckduckgo.com"); + WebElement inputTextEl = d.findElement(By.id("search_form_input_homepage")); + WebElement submitSearchDivWrapperEl = d.findElement(By.id("search_wrapper_homepage")); + WebElement submitSearchInputEl = d.findElement(By.id("search_button_homepage")); + + // Enter a query + inputTextEl.sendKeys("GhostDriver"); + + assertFalse(d.getTitle().contains("GhostDriver")); + // Ensure clicking on the Button DIV wrapper DOESN'T expect a pageload + submitSearchDivWrapperEl.click(); + assertFalse(d.getTitle().contains("GhostDriver")); + // Instead, clicking on the actual Input element DOES + submitSearchInputEl.click(); + assertTrue(d.getTitle().contains("GhostDriver")); + } + + @Test + public void shouldWaitForOnClickCallbackToFinishBeforeContinuing() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("\n" + + " Click Here"); + } + }); + + WebDriver d = getDriver(); + + d.get(server.getBaseUrl()); + d.findElement(By.xpath("html/body/a")).click(); + + assertTrue(d.getTitle().toLowerCase().contains("google")); + } + + @Test + public void shouldNotHandleCasesWhenAsyncJavascriptInitiatesAPageLoadFarInTheFuture() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("\n" + + " Click Here"); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Initiate timer that will finish with loading Google in the window + d.findElement(By.xpath("html/body/a")).click(); + + // "google.com" hasn't loaded yet at this stage + assertFalse(d.getTitle().toLowerCase().contains("google")); + } + + @Test + public void shouldHandleCasesWhereJavascriptCodeInitiatesPageLoadsThatFail() throws InterruptedException { + final String crazyUrl = "http://abcdefghilmnopqrstuvz.zvutsr"; + + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("\n" + + " Click Here"); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Click on the link to kickstart the javascript that will attempt to load a page that is supposed to fail + d.findElement(By.xpath("html/body/a")).click(); + + // The crazy URL should have not been loaded + assertTrue(!d.getCurrentUrl().equals(crazyUrl)); + } + + + @Test + public void shouldUsePageTimeoutToWaitForPageLoadOnInput() throws InterruptedException { + WebDriver d = getDriver(); + String inputString = "clicking"; + + d.get("http://www.duckduckgo.com"); + WebElement textInput = d.findElement(By.cssSelector("#search_form_input_homepage")); + + assertFalse(d.getTitle().contains(inputString)); + textInput.click(); + assertFalse(d.getTitle().contains(inputString)); + + // This input will ALSO submit the search form, causing a Page Load + textInput.sendKeys(inputString + "\n"); + + assertTrue(d.getTitle().contains(inputString)); + } + + @Test + public void shouldUsePageTimeoutToWaitForPageLoadOnInput_negativeCase() throws InterruptedException { + WebDriver d = getDriver(); + String inputString = "clicking"; + + d.get("http://www.duckduckgo.com"); + WebElement textInput = d.findElement(By.cssSelector("#search_form_input_homepage")); + + assertFalse(d.getTitle().contains(inputString)); + textInput.click(); + assertFalse(d.getTitle().contains(inputString)); + + // Set Implicit Timeout to 0: this will force Driver to NOT wait + d.manage().timeouts().pageLoadTimeout(0, TimeUnit.MILLISECONDS); + // This input will ALSO submit the search form, causing a Page Load + textInput.sendKeys(inputString + "\n"); + + assertFalse(d.getTitle().contains(inputString)); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementQueryingTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementQueryingTest.java new file mode 100644 index 00000000..e415b564 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/ElementQueryingTest.java @@ -0,0 +1,148 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.*; +import org.openqa.selenium.internal.Locatable; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ElementQueryingTest extends BaseTestWithServer { + @Test + public void checkAttributesOnGoogleSearchBox() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + WebElement el = d.findElement(By.cssSelector("input[name*='q']")); + + assertTrue(el.getAttribute("name").toLowerCase().contains("q")); + assertTrue(el.getAttribute("type").toLowerCase().contains("text")); + assertTrue(el.getAttribute("style").length() > 0); + assertTrue(el.getAttribute("type").length() > 0); + } + + @Test + public void checkLocationAndSizeOfBingSearchBox() { + WebDriver d = getDriver(); + d.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS); + + d.get("http://www.bing.com"); + WebElement searchBox = d.findElement(By.cssSelector("input[name*='q']")); + + assertTrue(searchBox.getCssValue("color").contains("rgb(0, 0, 0)") || searchBox.getCssValue("color").contains("rgba(0, 0, 0, 1)")); + assertEquals("", searchBox.getAttribute("value")); + assertEquals("input", searchBox.getTagName()); + assertEquals(true, searchBox.isEnabled()); + assertEquals(true, searchBox.isDisplayed()); + assertTrue(searchBox.getLocation().getX() >= 200); + assertTrue(searchBox.getLocation().getY() >= 100); + assertTrue(searchBox.getSize().getWidth() >= 350); + assertTrue(searchBox.getSize().getHeight() >= 20); + } + + @Test + public void scrollElementIntoView() { + WebDriver d = getDriver(); + + d.get("https://developer.mozilla.org/en/CSS/Attribute_selectors"); + WebElement aboutGoogleLink = d.findElement(By.partialLinkText("About MDN")); + Point locationBeforeScroll = aboutGoogleLink.getLocation(); + Point locationAfterScroll = ((Locatable) aboutGoogleLink).getCoordinates().inViewPort(); + + assertTrue(locationBeforeScroll.x >= locationAfterScroll.x); + assertTrue(locationBeforeScroll.y >= locationAfterScroll.y); + } + + @Test + public void getTextFromDifferentLocationsOfDOMTree() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("" + + "
\n" + + " \n" + + " \n" + + "

The Title of The Item

\n" + + "
\n" + + "
\n" + + "
\n" + + " (Loads of other stuff)\n" + + "
\n" + + "
" + + ""); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + assertEquals("The Title of The Item\n(Loads of other stuff)", d.findElement(By.className("item")).getText()); + assertEquals("The Title of The Item", d.findElement(By.className("item")).findElement(By.tagName("h1")).getText()); + assertEquals("The Title of The Item", d.findElement(By.className("item")).findElement(By.tagName("a")).getText()); + assertEquals("The Title of The Item", d.findElement(By.className("item")).findElement(By.className("item-title")).getText()); + } + + @Test(expected = InvalidElementStateException.class) + public void throwExceptionWhenInteractingWithInvisibleElement() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("" + + "" + + " \n" + + " test\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " " + + ""); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + WebElement visibleInput = d.findElement(By.id("visible")); + WebElement invisibleInput = d.findElement(By.id("invisible")); + + String textToType = "text to type"; + visibleInput.sendKeys(textToType); + assertEquals(textToType, visibleInput.getAttribute("value")); + + invisibleInput.sendKeys(textToType); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/FileUploadTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/FileUploadTest.java new file mode 100644 index 00000000..4a1ef622 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/FileUploadTest.java @@ -0,0 +1,171 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.io.IOUtils; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FileUploadTest extends BaseTestWithServer { + private static final String LOREM_IPSUM_TEXT = "lorem ipsum dolor sit amet"; + private static final String FILE_HTML = "
" + LOREM_IPSUM_TEXT + "
"; + + @Test + public void checkFileUploadCompletes() throws IOException { + WebDriver d = getDriver(); + + // Create the test file for uploading + File testFile = File.createTempFile("webdriver", "tmp"); + testFile.deleteOnExit(); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(testFile.getAbsolutePath()), "utf-8")); + writer.write(FILE_HTML); + writer.close(); + + server.setHttpHandler("POST", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + if (ServletFileUpload.isMultipartContent(req) && req.getPathInfo().endsWith("/upload")) { + // Create a factory for disk-based file items + DiskFileItemFactory factory = new DiskFileItemFactory(1024, new File(System.getProperty("java.io.tmpdir"))); + + // Create a new file upload handler + ServletFileUpload upload = new ServletFileUpload(factory); + + // Parse the request + List items; + try { + items = upload.parseRequest(req); + } catch (FileUploadException fue) { + throw new IOException(fue); + } + + res.setHeader("Content-Type", "text/html; charset=UTF-8"); + InputStream is = items.get(0).getInputStream(); + OutputStream os = res.getOutputStream(); + IOUtils.copy(is, os); + + os.write("".getBytes()); + + IOUtils.closeQuietly(is); + IOUtils.closeQuietly(os); + return; + } + + res.sendError(400); + } + }); + + // Upload the temp file + d.get(server.getBaseUrl() + "/common/upload.html"); + d.findElement(By.id("upload")).sendKeys(testFile.getAbsolutePath()); + d.findElement(By.id("go")).submit(); + + // Uploading files across a network may take a while, even if they're really small. + // Wait for the loading label to disappear. + WebDriverWait wait = new WebDriverWait(d, 10); + wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("upload_label"))); + + d.switchTo().frame("upload_target"); + + wait = new WebDriverWait(d, 5); + wait.until(ExpectedConditions.textToBePresentInElementLocated(By.xpath("//body"), LOREM_IPSUM_TEXT)); + + // Navigate after file upload to verify callbacks are properly released. + d.get("http://www.google.com/"); + } + + @Test + public void checkFileUploadFailsIfFileDoesNotExist() throws InterruptedException { + WebDriver d = getDriver(); + + // Trying to upload a file that doesn't exist + d.get(server.getBaseUrl() + "/common/upload.html"); + d.findElement(By.id("upload")).sendKeys("file_that_does_not_exist.fake"); + d.findElement(By.id("go")).submit(); + + // Uploading files across a network may take a while, even if they're really small. + // Wait for a while and make sure the "upload_label" is still there: means that the file was not uploaded + Thread.sleep(1000); + assertTrue(d.findElement(By.id("upload_label")).isDisplayed()); + } + + @Test + public void checkUploadingTheSameFileMultipleTimes() throws IOException { + WebDriver d = getDriver(); + + File file = File.createTempFile("test", "txt"); + file.deleteOnExit(); + + d.get(server.getBaseUrl() + "/common/formPage.html"); + WebElement uploadElement = d.findElement(By.id("upload")); + uploadElement.sendKeys(file.getAbsolutePath()); + uploadElement.submit(); + + d.get(server.getBaseUrl() + "/common/formPage.html"); + uploadElement = d.findElement(By.id("upload")); + uploadElement.sendKeys(file.getAbsolutePath()); + uploadElement.submit(); + } + + @Test + public void checkOnChangeEventIsFiredOnFileUpload() throws IOException { + WebDriver d = getDriver(); + + d.get(server.getBaseUrl() + "/common/formPage.html"); + WebElement uploadElement = d.findElement(By.id("upload")); + WebElement result = d.findElement(By.id("fileResults")); + assertEquals("", result.getText()); + + File file = File.createTempFile("test", "txt"); + file.deleteOnExit(); + + uploadElement.sendKeys(file.getAbsolutePath()); + // Shift focus to something else because send key doesn't make the focus leave + d.findElement(By.id("id-name1")).click(); + + assertEquals("changed", result.getText()); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/FrameSwitchingTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/FrameSwitchingTest.java new file mode 100644 index 00000000..ee92613f --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/FrameSwitchingTest.java @@ -0,0 +1,492 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import com.google.common.base.Predicate; +import ghostdriver.server.GetFixtureHttpRequestCallback; +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.*; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import javax.annotation.Nullable; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static org.junit.Assert.*; + +public class FrameSwitchingTest extends BaseTestWithServer { + + private String getCurrentFrameName(WebDriver driver) { + return (String)((JavascriptExecutor) driver).executeScript("return window.frameElement ? " + + "window.frameElement.name : " + + "'__MAIN_FRAME__';"); + } + + private boolean isAtTopWindow(WebDriver driver) { + return (Boolean)((JavascriptExecutor) driver).executeScript("return window == window.top"); + } + + @Test + public void switchToFrameByNumber() { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame(0); + assertEquals("packageFrame", getCurrentFrameName(d)); + d.switchTo().defaultContent(); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame(0); + assertEquals("packageFrame", getCurrentFrameName(d)); + } + + @Test + public void switchToFrameByName() { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame("packageFrame"); + assertEquals("packageFrame", getCurrentFrameName(d)); + d.switchTo().defaultContent(); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame("packageFrame"); + assertEquals("packageFrame", getCurrentFrameName(d)); + } + + @Test + public void switchToFrameByElement() { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame(d.findElement(By.name("packageFrame"))); + assertEquals("packageFrame", getCurrentFrameName(d)); + d.switchTo().defaultContent(); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + d.switchTo().frame(d.findElement(By.name("packageFrame"))); + assertEquals("packageFrame", getCurrentFrameName(d)); + } + + @Test(expected = NoSuchFrameException.class) + public void failToSwitchToFrameByName() throws Exception { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + d.switchTo().frame("unavailable frame"); + } + + @Test(expected = NoSuchElementException.class) + public void shouldBeAbleToClickInAFrame() throws InterruptedException { + WebDriver d = getDriver(); + + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + + d.switchTo().frame("classFrame"); + assertEquals("classFrame", getCurrentFrameName(d)); + + // This should cause a reload in the frame "classFrame" + d.findElement(By.linkText("HttpClient")).click(); + + // Wait for new content to load in the frame. + WebDriverWait wait = new WebDriverWait(d, 10); + wait.until(ExpectedConditions.titleContains("HttpClient")); + + // Frame should still be "classFrame" + assertEquals("classFrame", getCurrentFrameName(d)); + + // Check if a link "clearCookies()" is there where expected + assertEquals("clearCookies", d.findElement(By.linkText("clearCookies")).getText()); + + // Make sure it was really frame "classFrame" which was replaced: + // 1. move to the other frame "packageFrame" + d.switchTo().defaultContent().switchTo().frame("packageFrame"); + assertEquals("packageFrame", getCurrentFrameName(d)); + // 2. the link "clearCookies()" shouldn't be there anymore + d.findElement(By.linkText("clearCookies")); + } + + @Test(expected = NoSuchElementException.class) + public void shouldBeAbleToClickInAFrameAfterRunningJavaScript() throws InterruptedException { + WebDriver d = getDriver(); + + // Navigate to page and ensure we are on the Main Frame + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + assertTrue(isAtTopWindow(d)); + d.switchTo().defaultContent(); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + assertTrue(isAtTopWindow(d)); + + // Switch to a child frame + d.switchTo().frame("classFrame"); + assertEquals("classFrame", getCurrentFrameName(d)); + assertFalse(isAtTopWindow(d)); + + // Renavigate to the page, and check we are back on the Main Frame + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + assertTrue(isAtTopWindow(d)); + // Switch to a child frame + d.switchTo().frame("classFrame"); + assertEquals("classFrame", getCurrentFrameName(d)); + assertFalse(isAtTopWindow(d)); + + // This should cause a reload in the frame "classFrame" + d.findElement(By.linkText("HttpClient")).click(); + + // Wait for new content to load in the frame. + WebDriverWait wait = new WebDriverWait(d, 10); + wait.until(ExpectedConditions.titleContains("HttpClient")); + + // Frame should still be "classFrame" + assertEquals("classFrame", getCurrentFrameName(d)); + + // Check if a link "clearCookies()" is there where expected + assertEquals("clearCookies", d.findElement(By.linkText("clearCookies")).getText()); + + // Make sure it was really frame "classFrame" which was replaced: + // 1. move to the other frame "packageFrame" + d.switchTo().defaultContent().switchTo().frame("packageFrame"); + assertEquals("packageFrame", getCurrentFrameName(d)); + // 2. the link "clearCookies()" shouldn't be there anymore + d.findElement(By.linkText("clearCookies")); + } + + @Test + public void titleShouldReturnWindowTitle() { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + assertEquals("__MAIN_FRAME__", getCurrentFrameName(d)); + String topLevelTitle = d.getTitle(); + d.switchTo().frame("packageFrame"); + assertEquals("packageFrame", getCurrentFrameName(d)); + assertEquals(topLevelTitle, d.getTitle()); + d.switchTo().defaultContent(); + assertEquals(topLevelTitle, d.getTitle()); + } + + @Test + public void pageSourceShouldReturnSourceOfFocusedFrame() throws InterruptedException { + WebDriver d = getDriver(); + d.get("http://docs.wpm.neustar.biz/testscript-api/index.html"); + + // Compare source before and after the frame switch + String pageSource = d.getPageSource(); + d.switchTo().frame("classFrame"); + String framePageSource = d.getPageSource(); + assertFalse(pageSource.equals(framePageSource)); + + assertTrue("Page source was: " + framePageSource, framePageSource.contains("Interface Summary")); + } + + @Test + public void shouldSwitchBackToMainFrameIfLinkInFrameCausesTopFrameReload() throws Exception { + WebDriver d = getDriver(); + String expectedTitle = "Unique title"; + + class SpecialHttpRequestCallback extends GetFixtureHttpRequestCallback { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + if (req.getPathInfo().matches("^.*page/\\d+$")) { + int lastIndex = req.getPathInfo().lastIndexOf('/'); + String pageNumber = + (lastIndex == -1 ? "Unknown" : req.getPathInfo().substring(lastIndex + 1)); + String resBody = String.format("Page%s" + + "Page number %s" + + "

top" + + "", + pageNumber, pageNumber); + + res.getOutputStream().println(resBody); + } else { + super.call(req, res); + } + } + } + + server.setHttpHandler("GET", new SpecialHttpRequestCallback()); + + d.get(server.getBaseUrl() + "/common/frameset.html"); + assertEquals(expectedTitle, d.getTitle()); + + d.switchTo().frame(0); + d.findElement(By.linkText("top")).click(); + + // Wait for new content to load in the frame. + expectedTitle = "XHTML Test Page"; + WebDriverWait wait = new WebDriverWait(d, 10); + wait.until(ExpectedConditions.titleIs(expectedTitle)); + assertEquals(expectedTitle, d.getTitle()); + + WebElement element = d.findElement(By.id("amazing")); + assertNotNull(element); + } + + @Test + public void shouldSwitchBetweenNestedFrames() { + // Define HTTP response for test + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + String pathInfo = req.getPathInfo(); + ServletOutputStream out = res.getOutputStream(); + + // NOTE: the following pages are cut&paste from "Watir" test specs. + // @see https://github.com/watir/watirspec/tree/master/html/nested_frame.html + if (pathInfo.endsWith("nested_frame_1.html")) { + // nested frame 1 + out.println("frame 1"); + } else if (pathInfo.endsWith("nested_frame_2.html")) { + // nested frame 2 + out.println("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + ""); + } else if (pathInfo.endsWith("nested_frame_3.html")) { + // nested frame 3, nested inside frame 2 + out.println("\n" + + "\n" + + " \n" + + " this link should consume the page\n" + + " \n" + + ""); + } else if (pathInfo.endsWith("definition_lists.html")) { + // definition lists + out.println("\n" + + " \n" + + " definition_lists\n" + + " \n" + + ""); + } else { + // main page + out.println("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""); + } + } + }); + + // Launch Driver against the above defined server + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Switch to frame "#two" + d.switchTo().frame("two"); + // Switch further down into frame "#three" + d.switchTo().frame("three"); + // Click on the link in frame "#three" + d.findElement(By.id("four")).click(); + + // Expect page to have loaded and title to be set correctly + new WebDriverWait(d, 5).until(ExpectedConditions.titleIs("definition_lists")); + } + + @Test + public void shouldSwitchBetweenNestedFramesPickedViaWebElement() { + // Define HTTP response for test + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + String pathInfo = req.getPathInfo(); + ServletOutputStream out = res.getOutputStream(); + + // NOTE: the following pages are cut&paste from "Watir" test specs. + // @see https://github.com/watir/watirspec/tree/master/html/nested_frame.html + if (pathInfo.endsWith("nested_frame_1.html")) { + // nested frame 1 + out.println("frame 1"); + } else if (pathInfo.endsWith("nested_frame_2.html")) { + // nested frame 2 + out.println("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + ""); + } else if (pathInfo.endsWith("nested_frame_3.html")) { + // nested frame 3, nested inside frame 2 + out.println("\n" + + "\n" + + " \n" + + " this link should consume the page\n" + + " \n" + + ""); + } else if (pathInfo.endsWith("definition_lists.html")) { + // definition lists + out.println("\n" + + " \n" + + " definition_lists\n" + + " \n" + + ""); + } else { + // main page + out.println("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""); + } + } + }); + + // Launch Driver against the above defined server + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Switch to frame "#two" + d.switchTo().frame(d.findElement(By.id("two"))); + // Switch further down into frame "#three" + d.switchTo().frame(d.findElement(By.id("three"))); + // Click on the link in frame "#three" + d.findElement(By.id("four")).click(); + + // Expect page to have loaded and title to be set correctly + new WebDriverWait(d, 5).until(ExpectedConditions.titleIs("definition_lists")); + } + + @Test + public void shouldBeAbleToSwitchToIFrameThatHasNoNameNorId() { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("" + + "" + + " " + + "" + + ""); + } + }); + + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + WebElement el = d.findElement(By.tagName("iframe")); + d.switchTo().frame(el); + } + + @Test(expected = TimeoutException.class) + public void shouldTimeoutWhileChangingIframeSource() { + final String iFrameId = "iframeId"; + + // Define HTTP response for test + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + String pathInfo = req.getPathInfo(); + ServletOutputStream out = res.getOutputStream(); + + if (pathInfo.endsWith("iframe_content.html")) { + // nested frame 1 + out.println("iframe content"); + } else { + // main page + out.println("\n" + + "\n" + + " \n" + + " \n" + + "\n" + + ""); + } + } + }); + + // Launch Driver against the above defined server + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Switch to iframe + d.switchTo().frame(iFrameId); + assertEquals(0, d.findElements(By.id(iFrameId)).size()); + assertFalse(d.getPageSource().toLowerCase().contains("iframe content")); + + new WebDriverWait(d, 5).until(new Predicate() { + @Override + public boolean apply(@Nullable WebDriver driver) { + assertEquals(0, driver.findElements(By.id(iFrameId)).size()); + return (Boolean) ((JavascriptExecutor) driver).executeScript("return false;"); + } + }); + } + + @Test + public void shouldSwitchToTheRightFrame() { + WebDriver d = getDriver(); + + // Load "outside.html" and check it's the right one + d.get(server.getBaseUrl() + "right_frame/outside.html"); + assertTrue(d.getPageSource().contains("Editing testDotAtEndDoesNotDelete")); + assertEquals(2, d.findElements(By.tagName("iframe")).size()); + + // Find the iframe with class "gwt-RichTextArea" + WebElement iframeRichTextArea = d.findElement(By.className("gwt-RichTextArea")); + + // Switch to the iframe via WebElement and check it's the right one + d.switchTo().frame(iframeRichTextArea); + assertEquals(0, d.findElements(By.tagName("title")).size()); + assertFalse(d.getPageSource().contains("Editing testDotAtEndDoesNotDelete")); + assertEquals(0, d.findElements(By.tagName("iframe")).size()); + + // Switch back to the main frame and check it's the right one + d.switchTo().defaultContent(); + assertEquals(2, d.findElements(By.tagName("iframe")).size()); + + // Switch again to the iframe, this time via it's "frame number" (i.e. 0 to n) + d.switchTo().frame(0); + assertEquals(0, d.findElements(By.tagName("title")).size()); + assertFalse(d.getPageSource().contains("Editing testDotAtEndDoesNotDelete")); + assertEquals(0, d.findElements(By.tagName("iframe")).size()); + + // Switch back to the main frame and check it's the right one + d.switchTo().defaultContent(); + assertEquals(2, d.findElements(By.tagName("iframe")).size()); + + // Switch to the second frame via it's "frame number" + d.switchTo().frame(1); + assertEquals(1, d.findElements(By.tagName("title")).size()); + assertEquals(0, d.findElements(By.tagName("iframe")).size()); + assertTrue(d.getPageSource().contains("WYSIWYG Editor Input Template")); + + // Switch again to the main frame + d.switchTo().defaultContent(); + assertEquals(2, d.findElements(By.tagName("iframe")).size()); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/GoogleSearchTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/GoogleSearchTest.java new file mode 100644 index 00000000..20547a99 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/GoogleSearchTest.java @@ -0,0 +1,55 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import static org.junit.Assert.assertTrue; + +public class GoogleSearchTest extends BaseTest { + @Test + public void searchForCheese() { + String strToSearchFor = "Cheese!"; + WebDriver d = getDriver(); + + // Load Google.com + d.get(" http://www.google.com"); + // Locate the Search field on the Google page + WebElement element = d.findElement(By.name("q")); + // Type Cheese + element.sendKeys(strToSearchFor); + // Submit form + element.submit(); + + // Check results contains the term we searched for + assertTrue(d.getTitle().toLowerCase().contains(strToSearchFor.toLowerCase())); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/IsolatedSessionTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/IsolatedSessionTest.java new file mode 100644 index 00000000..2299dd26 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/IsolatedSessionTest.java @@ -0,0 +1,55 @@ +package ghostdriver; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.Cookie; +import org.openqa.selenium.WebDriver; + +import java.util.Set; + +import static org.junit.Assert.assertFalse; + +public class IsolatedSessionTest extends BaseTest { + // New Session Cookies will be stored in here + private String url = "http://www.google.com"; + private Set sessionCookies; + + @Before + public void createSession() throws Exception { + disableAutoQuitDriver(); + + WebDriver d = getDriver(); + d.get(url); + + // Grab set of session cookies + sessionCookies = d.manage().getCookies(); + + // Manually quit the current Driver and create a new one + d.quit(); + prepareDriver(); + } + + @Test + public void shouldCreateASeparateSessionWithEveryNewDriverInstance() { + WebDriver d = getDriver(); + d.get(url); + + // Grab NEW set of session cookies + Set newSessionCookies = d.manage().getCookies(); + + // No cookie of the new Session can be found in the cookies of the old Session + for (Cookie c : sessionCookies) { + assertFalse(newSessionCookies.contains(c)); + } + // No cookie of the old Session can be found in the cookies of the new Session + for (Cookie c : newSessionCookies) { + assertFalse(sessionCookies.contains(c)); + } + } + + @After + public void quitDriver() { + getDriver().quit(); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/LogTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/LogTest.java new file mode 100644 index 00000000..217d1f95 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/LogTest.java @@ -0,0 +1,90 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.logging.LogEntries; +import org.openqa.selenium.logging.LogEntry; + +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class LogTest extends BaseTestWithServer { + @Test + public void shouldReturnListOfAvailableLogs() { + WebDriver d = getDriver(); + Set logTypes = d.manage().logs().getAvailableLogTypes(); + + if (d.getClass().getSimpleName().equals("PhantomJSDriver")) { + // GhostDriver only has 3 log types... + assertEquals(3, logTypes.size()); + // ... and "har" is one of them + assertTrue(logTypes.contains("har")); + } else { + assertTrue(logTypes.size() >= 2); + } + assertTrue(logTypes.contains("client")); + assertTrue(logTypes.contains("browser")); + + } + + @Test + public void shouldReturnLogTypeBrowser() { + WebDriver d = getDriver(); + d.get(server.getBaseUrl() + "/common/errors.html"); + // Throw 3 errors that are logged in the Browser's console + WebElement throwErrorButton = d.findElement(By.cssSelector("input[type='button']")); + throwErrorButton.click(); + throwErrorButton.click(); + throwErrorButton.click(); + + // Retrieve and count the errors + LogEntries logEntries = d.manage().logs().get("browser"); + assertEquals(3, logEntries.getAll().size()); + + for (LogEntry logEntry : logEntries) { + System.out.println(logEntry); + } + } + + @Test + public void shouldReturnLogTypeHar() { + WebDriver d = getDriver(); + d.get(server.getBaseUrl() + "/common/iframes.html"); + + LogEntries logEntries = d.manage().logs().get("har"); + for (LogEntry logEntry : logEntries) { + System.out.println(logEntry); + } + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/MouseCommandsTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/MouseCommandsTest.java new file mode 100644 index 00000000..02a3ccf8 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/MouseCommandsTest.java @@ -0,0 +1,132 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class MouseCommandsTest extends BaseTestWithServer { + @Test + public void move() { + WebDriver d = getDriver(); + Actions actionBuilder = new Actions(d); + + d.get("http://www.duckduckgo.com"); + + // Move mouse by x,y + actionBuilder.moveByOffset(100, 100).build().perform(); + // Move mouse on a given element + actionBuilder.moveToElement(d.findElement(By.id("logo_homepage"))).build().perform(); + // Move mouse on a given element, by x,y relative coordinates + actionBuilder.moveToElement(d.findElement(By.id("logo_homepage")), 50, 50).build().perform(); + } + + @Test + public void clickAndRightClick() { + WebDriver d = getDriver(); + Actions actionBuilder = new Actions(d); + + d.get("http://www.duckduckgo.com"); + + // Left click + actionBuilder.click().build().perform(); + // Right click + actionBuilder.contextClick(null).build().perform(); + // Right click on the logo (it will cause a "/moveto" before clicking + actionBuilder.contextClick(d.findElement(By.id("logo_homepage"))).build().perform(); + } + + @Test + public void doubleClick() { + WebDriver d = getDriver(); + Actions actionBuilder = new Actions(d); + + d.get("http://www.duckduckgo.com"); + + // Double click + actionBuilder.doubleClick().build().perform(); + // Double click on the logo + actionBuilder.doubleClick(d.findElement(By.id("logo_homepage"))).build().perform(); + } + + @Test + public void clickAndHold() { + WebDriver d = getDriver(); + Actions actionBuilder = new Actions(d); + + d.get("http://www.duckduckgo.com"); + + // Hold, then release + actionBuilder.clickAndHold().build().perform(); + actionBuilder.release(); + // Hold on the logo, then release + actionBuilder.clickAndHold(d.findElement(By.id("logo_homepage"))).build().perform(); + actionBuilder.release(); + } + + @Test + public void handleClickWhenOnClickInlineCodeFails() { + // Define HTTP response for test + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("" + + "" + + "\n" + + "" + + "" + + "\n" + + "Click me" + + "" + + ""); + } + }); + + // Navigate to local server + WebDriver d = getDriver(); + d.navigate().to(server.getBaseUrl()); + + WebElement el = d.findElement(By.linkText("Click me")); + el.click(); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/NavigationTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/NavigationTest.java new file mode 100644 index 00000000..6360e369 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/NavigationTest.java @@ -0,0 +1,90 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.phantomjs.PhantomJSDriverService; + +import static org.junit.Assert.assertTrue; + +public class NavigationTest extends BaseTest { + @BeforeClass + public static void setUserAgentForPhantomJSDriver() { + // Setting a generic Chrome UA to bypass some UA spoofing + sCaps.setCapability( + PhantomJSDriverService.PHANTOMJS_PAGE_SETTINGS_PREFIX + "userAgent", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11" + ); + } + + @Test + public void navigateAroundMDN() { + WebDriver d = getDriver(); + + d.get("https://developer.mozilla.org/en-US/"); + assertTrue(d.getTitle().toLowerCase().contains("Mozilla".toLowerCase())); + d.navigate().to("https://developer.mozilla.org/en/HTML/HTML5"); + assertTrue(d.getTitle().toLowerCase().contains("HTML5".toLowerCase())); + d.navigate().refresh(); + assertTrue(d.getTitle().toLowerCase().contains("HTML5".toLowerCase())); + d.navigate().back(); + assertTrue(d.getTitle().toLowerCase().contains("Mozilla".toLowerCase())); + d.navigate().forward(); + assertTrue(d.getTitle().toLowerCase().contains("HTML5".toLowerCase())); + } + + @Test + public void navigateBackWithNoHistory() throws Exception { + // Fresh Driver (every test gets one) + WebDriver d = getDriver(); + + // Navigate back and forward: should be a no-op, given we haven't loaded anything yet + d.navigate().back(); + d.navigate().forward(); + + // Make sure explicit navigation still works. + d.get("http://google.com"); + } + + @Test + public void navigateToGoogleAdwords() { + WebDriver d = getDriver(); + d.get("http://adwords.google.com"); + assertTrue(d.getCurrentUrl().contains("google.com")); + } + + @Test + public void navigateToNameJet() { + // NOTE: This passes only when the User Agent is NOT PhantomJS {@see setUserAgentForPhantomJSDriver} + // method above. + WebDriver d = getDriver(); + d.navigate().to("http://www.namejet.com/"); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/PhantomJSCommandTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/PhantomJSCommandTest.java new file mode 100755 index 00000000..56c1eeec --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/PhantomJSCommandTest.java @@ -0,0 +1,49 @@ +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.phantomjs.PhantomJSDriver; + +import static junit.framework.TestCase.assertEquals; + +public class PhantomJSCommandTest extends BaseTest { + @Test + public void executePhantomJS() { + WebDriver d = getDriver(); + if (!(d instanceof PhantomJSDriver)) { + // Skip this test if not using PhantomJS. + // The command under test is only available when using PhantomJS + return; + } + + PhantomJSDriver phantom = (PhantomJSDriver)d; + + // Do we get results back? + Object result = phantom.executePhantomJS("return 1 + 1"); + assertEquals(new Long(2), (Long)result); + + // Can we read arguments? + result = phantom.executePhantomJS("return arguments[0] + arguments[0]", new Long(1)); + assertEquals(new Long(2), (Long)result); + + // Can we override some browser JavaScript functions in the page context? + result = phantom.executePhantomJS("var page = this;" + + "page.onInitialized = function () { " + + "page.evaluate(function () { " + + "Math.random = function() { return 42 / 100 } " + + "})" + + "}"); + + phantom.get("http://ariya.github.com/js/random/"); + + WebElement numbers = phantom.findElement(By.id("numbers")); + boolean foundAtLeastOne = false; + for(String number : numbers.getText().split(" ")) { + foundAtLeastOne = true; + assertEquals("42", number); + } + assert(foundAtLeastOne); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/ScriptExecutionTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/ScriptExecutionTest.java new file mode 100644 index 00000000..fe38cbbd --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/ScriptExecutionTest.java @@ -0,0 +1,135 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.Ignore; +import org.junit.Test; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.*; + +public class ScriptExecutionTest extends BaseTest { + @Test + public void findGoogleInputFieldInjectingJavascript() { + WebDriver d = getDriver(); + d.get("http://www.google.com"); + WebElement e = (WebElement)((JavascriptExecutor) d).executeScript( + "return document.querySelector(\"[name='\"+arguments[0]+\"']\");", + "q"); + assertNotNull(e); + assertEquals("input", e.getTagName().toLowerCase()); + } + + @Test + public void setTimeoutAsynchronously() { + WebDriver d = getDriver(); + d.get("http://www.google.com"); + String res = (String)((JavascriptExecutor) d).executeAsyncScript( + "window.setTimeout(arguments[arguments.length - 1], arguments[0], 'done');", + 1000); + assertEquals("done", res); + } + + @Test + public void shouldBeAbleToPassMultipleArgumentsToAsyncScripts() { + WebDriver d = getDriver(); + d.manage().timeouts().setScriptTimeout(0, TimeUnit.MILLISECONDS); + d.get("http://www.google.com/"); + Number result = (Number) ((JavascriptExecutor) d).executeAsyncScript( + "arguments[arguments.length - 1](arguments[0] + arguments[1]);", + 1, + 2); + assertEquals(3, result.intValue()); + + // Verify that a future navigation does not cause the driver to have problems. + d.get("http://www.google.com/"); + } + + @Test + public void shouldBeAbleToExecuteMultipleAsyncScriptsSequentially() { + WebDriver d = getDriver(); + d.manage().timeouts().setScriptTimeout(0, TimeUnit.MILLISECONDS); + d.get("http://www.google.com/"); + Number numericResult = (Number) ((JavascriptExecutor) d).executeAsyncScript( + "arguments[arguments.length - 1](123);"); + assertEquals(123, numericResult.intValue()); + String stringResult = (String) ((JavascriptExecutor) d).executeAsyncScript( + "arguments[arguments.length - 1]('abc');"); + assertEquals("abc", stringResult); + } + + @Test + public void shouldBeAbleToExecuteMultipleAsyncScriptsSequentiallyWithNavigation() { + // NOTE: This test is supposed to fail! + // It's a reminder that there is some internal issue in PhantomJS still to address. + + WebDriver d = getDriver(); + d.manage().timeouts().setScriptTimeout(0, TimeUnit.MILLISECONDS); + + d.get("http://www.google.com/"); + Number numericResult = (Number) ((JavascriptExecutor) d).executeAsyncScript( + "arguments[arguments.length - 1](123);"); + assertEquals(123, numericResult.intValue()); + + d.get("http://www.google.com/"); + String stringResult = (String) ((JavascriptExecutor) d).executeAsyncScript( + "arguments[arguments.length - 1]('abc');"); + assertEquals("abc", stringResult); + + // Verify that a future navigation does not cause the driver to have problems. + d.get("http://www.google.com/"); + } + + @Ignore("Known issue #140 - see https://github.com/detro/ghostdriver/issues/140)") + @Test + public void executeAsyncScriptMultipleTimesWithoutCrashing() { + // NOTE: This test is supposed to fail! + // It's a reminder that there is some internal issue in PhantomJS still to address. + + WebDriver d = getDriver(); + + String hello = null; + try { + hello = URLEncoder.encode("

hello

", "UTF-8"); + } catch (UnsupportedEncodingException uee) { + fail(); + } + + for (int i = 1; i < 5; ++i) { + d.get("data:text/html;content-type=utf-8,"+hello); + String h = (String)((JavascriptExecutor) d).executeAsyncScript("arguments[arguments.length - 1]('hello')"); + assertEquals("hello", h); + } + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/SessionBasicTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/SessionBasicTest.java new file mode 100644 index 00000000..5ec1645d --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/SessionBasicTest.java @@ -0,0 +1,59 @@ +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.NoSuchWindowException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.remote.SessionNotFoundException; + +import java.net.MalformedURLException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class SessionBasicTest extends BaseTest { + + @Test(expected = SessionNotFoundException.class) + public void quitShouldTerminatePhantomJSProcess() throws MalformedURLException { + // Get Driver Instance + WebDriver d = getDriver(); + d.navigate().to("about:blank"); + + // Quit the driver, that will cause the process to close + d.quit(); + + // Throws "SessionNotFoundException", because no process is actually left to respond + d.getWindowHandle(); + } + + @Test(expected = NoSuchWindowException.class) + public void closeShouldNotTerminatePhantomJSProcess() throws MalformedURLException { + // By default, 1 window is created when Driver is launched + WebDriver d = getDriver(); + assertEquals(1, d.getWindowHandles().size()); + + // Check the number of windows + d.navigate().to("about:blank"); + assertEquals(1, d.getWindowHandles().size()); + + // Create a new window + ((JavascriptExecutor) d).executeScript("window.open('http://www.google.com','google');"); + assertEquals(2, d.getWindowHandles().size()); + + // Close 1 window and check that 1 is left + d.close(); + assertEquals(1, d.getWindowHandles().size()); + + // Switch to that window + d.switchTo().window("google"); + assertNotNull(d.getWindowHandle()); + + // Close the remaining window and check now there are no windows available + d.close(); + assertEquals(0, d.getWindowHandles().size()); + + // This should throw a "NoSuchWindowException": the Driver is still running, but no Session/Window are left + d.getWindowHandle(); + } + +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/TimeoutSettingTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/TimeoutSettingTest.java new file mode 100644 index 00000000..4ffa97b1 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/TimeoutSettingTest.java @@ -0,0 +1,43 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.WebDriver; + +import java.util.concurrent.TimeUnit; + +public class TimeoutSettingTest extends BaseTest { + @Test + public void navigateAroundMDN() { + WebDriver d = getDriver(); + d.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + d.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS); + d.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowHandlesTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowHandlesTest.java new file mode 100644 index 00000000..2338eb42 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowHandlesTest.java @@ -0,0 +1,103 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import ghostdriver.server.HttpRequestCallback; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +import static org.junit.Assert.*; + +public class WindowHandlesTest extends BaseTestWithServer { + @Test + public void enumerateWindowHandles() { + WebDriver d = getDriver(); + + // Didn't open any page yet: no Window Handles yet + Set whandles = d.getWindowHandles(); + assertEquals(whandles.size(), 1); + + // Open Google and count the Window Handles: there should be at least 1 + d.get("http://www.google.com"); + whandles = d.getWindowHandles(); + assertEquals(whandles.size(), 1); + } + + @Test + public void enumerateWindowHandle() { + WebDriver d = getDriver(); + + // Didn't open any page yet: no Window Handles yet + String whandle = d.getWindowHandle(); + assertFalse(whandle.isEmpty()); + } + + @Test + public void openPopupAndGetCurrentUrl() throws InterruptedException { + server.setHttpHandler("GET", new HttpRequestCallback() { + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println("" + + "" + + "\n" + + "\n" + + " \n" + + " Link to popup" + + " \n" + + ""); + } + }); + + // Load page + WebDriver d = getDriver(); + d.get(server.getBaseUrl()); + + // Click on link that will cause popup to be created + d.findElement(By.xpath("//a")).click(); + // Switch to new popup + String popupHandle = (String)d.getWindowHandles().toArray()[1]; + d.switchTo().window(popupHandle); + + assertTrue(d.getTitle().contains("Japan")); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSizingAndPositioningTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSizingAndPositioningTest.java new file mode 100644 index 00000000..4d0c04d6 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSizingAndPositioningTest.java @@ -0,0 +1,78 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import org.junit.Test; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebDriver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class WindowSizingAndPositioningTest extends BaseTest { + @Test + public void manipulateWindowSize() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + assertTrue(d.manage().window().getSize().width > 100); + assertTrue(d.manage().window().getSize().height > 100); + + d.manage().window().setSize(new Dimension(1024, 768)); + assertEquals(d.manage().window().getSize().width, 1024); + assertEquals(d.manage().window().getSize().height, 768); + } + + @Test + public void manipulateWindowPosition() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + assertTrue(d.manage().window().getPosition().x >= 0); + assertTrue(d.manage().window().getPosition().y >= 0); + + d.manage().window().setPosition(new Point(0, 0)); + assertTrue(d.manage().window().getPosition().x == 0); + assertTrue(d.manage().window().getPosition().y == 0); + } + + @Test + public void manipulateWindowMaximize() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + + Dimension sizeBefore = d.manage().window().getSize(); + d.manage().window().maximize(); + Dimension sizeAfter = d.manage().window().getSize(); + + assertTrue(sizeBefore.width <= sizeAfter.width); + assertTrue(sizeBefore.height <= sizeAfter.height); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSwitchingTest.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSwitchingTest.java new file mode 100644 index 00000000..8fef2658 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/WindowSwitchingTest.java @@ -0,0 +1,220 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver; + +import com.google.common.base.Function; +import org.junit.Test; +import org.openqa.selenium.*; +import org.openqa.selenium.support.ui.WebDriverWait; + +import javax.annotation.Nullable; + +import static org.junit.Assert.*; + +public class WindowSwitchingTest extends BaseTestWithServer { + @Test + public void switchBetween3WindowsThenDeleteSecondOne() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + String googleWH = d.getWindowHandle(); + assertEquals(d.getWindowHandles().size(), 1); + + // Open a new window and make sure the window handle is different + ((JavascriptExecutor) d).executeScript("window.open('http://www.yahoo.com', 'yahoo')"); + assertEquals(d.getWindowHandles().size(), 2); + String yahooWH = (String) d.getWindowHandles().toArray()[1]; + assertTrue(!yahooWH.equals(googleWH)); + + // Switch to the yahoo window and check that the current window handle has changed + d.switchTo().window(yahooWH); + assertEquals(d.getWindowHandle(), yahooWH); + + // Open a new window and make sure the window handle is different + ((JavascriptExecutor) d).executeScript("window.open('http://www.bing.com', 'bing')"); + assertEquals(d.getWindowHandles().size(), 3); + String bingWH = (String) d.getWindowHandles().toArray()[2]; + assertTrue(!bingWH.equals(googleWH)); + assertTrue(!bingWH.equals(yahooWH)); + + // Close yahoo window + d.close(); + + // Switch to google window and notice that only google and bing are left + d.switchTo().window(googleWH); + assertEquals(d.getWindowHandles().size(), 2); + assertTrue(d.getWindowHandles().contains(googleWH)); + assertTrue(d.getWindowHandles().contains(bingWH)); + } + + @Test(expected = NoSuchWindowException.class) + public void switchBetween3WindowsThenDeleteFirstOne() { + WebDriver d = getDriver(); + + d.get("http://www.google.com"); + String googleWH = d.getWindowHandle(); + assertEquals(d.getWindowHandles().size(), 1); + + // Open a new window and make sure the window handle is different + ((JavascriptExecutor) d).executeScript("window.open('http://www.yahoo.com', 'yahoo')"); + assertEquals(d.getWindowHandles().size(), 2); + String yahooWH = (String) d.getWindowHandles().toArray()[1]; + assertTrue(!yahooWH.equals(googleWH)); + + // Switch to the yahoo window and check that the current window handle has changed + d.switchTo().window(yahooWH); + assertEquals(d.getWindowHandle(), yahooWH); + + // Open a new window and make sure the window handle is different + ((JavascriptExecutor) d).executeScript("window.open('http://www.bing.com', 'bing')"); + assertEquals(d.getWindowHandles().size(), 3); + String bingWH = (String) d.getWindowHandles().toArray()[2]; + assertTrue(!bingWH.equals(googleWH)); + assertTrue(!bingWH.equals(yahooWH)); + + // Switch to google window and close it + d.switchTo().window(googleWH); + d.close(); + + // Notice that yahoo and bing are the only left + assertEquals(d.getWindowHandles().size(), 2); + assertTrue(d.getWindowHandles().contains(yahooWH)); + assertTrue(d.getWindowHandles().contains(bingWH)); + + // Try getting the title of the, now closed, google window and cause an Exception + d.getTitle(); + } + + @Test + public void switchToSameWindowViaHandle() { + WebDriver d = getDriver(); + d.navigate().to(server.getBaseUrl() + "/common/frameset.html"); + + // Get handle of the main html page + String windowHandle = d.getWindowHandle(); + + // Verify that the element can be retrieved from the main page: + WebElement e = d.findElement(By.tagName("frameset")); + assertNotNull(e); + + // Switch to the frame. + d.switchTo().frame(0); + e = null; + try { + e = d.findElement(By.tagName("frameset")); + } catch (NoSuchElementException ex) { + // swallow the exception + } + assertNull(e); + + // Switch back to the main page using the original window handle: + d.switchTo().window(windowHandle); + + // This then throws an element not found exception.. the main page was not selected. + e = d.findElement(By.tagName("frameset")); + assertNotNull(e); + } + + @Test + public void shouldBeAbleToClickALinkThatClosesAWindow() throws Exception { + final WebDriver d = getDriver(); + d.get(server.getBaseUrl() + "/common/javascriptPage.html"); + + String handle = d.getWindowHandle(); + d.findElement(By.id("new_window")).click(); + + // Wait until we can switch to the new window + WebDriverWait waiter = new WebDriverWait(d, 10); + waiter.until(new Function() { + @Override + public Object apply(@Nullable WebDriver input) { + try { + d.switchTo().window("close_me"); + return true; + } catch (Exception e) { + return false; + } + } + }); + assertEquals(0, d.findElements(By.id("new_window")).size()); + + // Click on the "close" link. + // NOTE : This will cause the window currently in focus to close + d.findElement(By.id("close")).click(); + + d.switchTo().window(handle); + assertNotNull(d.findElement(By.id("new_window"))); + + // NOTE: If we haven't seen an exception or hung the test has passed + } + + @Test + public void shouldNotBeAbleToSwitchBackToInitialWindowUsingEmptyWindowNameParameter() { + final WebDriver d = getDriver(); + + d.get(server.getBaseUrl() + "/common/xhtmlTest.html"); + + // Store the first window handle + String initialWindowHandle = d.getWindowHandle(); + + // Ensure we are where we think we are, then click on "windowOne" to open another window + assertEquals(1, d.findElements(By.name("windowOne")).size()); + d.findElement(By.name("windowOne")).click(); + + // Wait until we can switch to the new window + WebDriverWait waiter = new WebDriverWait(d, 10); + waiter.until(new Function() { + @Override + public Object apply(@Nullable WebDriver input) { + try { + d.switchTo().window("result"); + return true; + } catch (Exception e) { + return false; + } + } + }); + // Check we are on the new window + assertEquals(1, d.findElements(By.id("greeting")).size()); + + // Switch to the first screen that has "window.name = ''". Usually, the first window of the Session. + d.switchTo().window(""); + // Close the window + d.close(); + + try { + // This second call to switch to window with empty string should fail. + // NOTE: I can't use "@Test(expected..." because the first call might throw the same exception + // and we won't be able to distinguish. + d.switchTo().window(""); + fail(); + } catch (NoSuchWindowException nswe) { + // If we are here, all is happening as expected + } + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackHttpServer.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackHttpServer.java new file mode 100644 index 00000000..de57db47 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackHttpServer.java @@ -0,0 +1,79 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver.server; + +import org.mortbay.jetty.Server; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.ServletHolder; + +import java.util.HashMap; +import java.util.Map; + +import static java.lang.String.format; + +public class CallbackHttpServer { + + protected Server server; + protected final Map httpReqCallbacks = new HashMap(); + + public CallbackHttpServer() { + // Default HTTP GET request callback: returns files in "test/fixture" + setHttpHandler("GET", new GetFixtureHttpRequestCallback()); + } + + public HttpRequestCallback getHttpHandler(String httpMethod) { + return httpReqCallbacks.get(httpMethod.toUpperCase()); + } + + public void setHttpHandler(String httpMethod, HttpRequestCallback getHandler) { + httpReqCallbacks.put(httpMethod.toUpperCase(), getHandler); + } + + public void start() throws Exception { + server = new Server(0); + Context context = new Context(server, "/"); + addServlets(context); + server.start(); + } + + public void stop() throws Exception { + server.stop(); + } + + protected void addServlets(Context context) { + context.addServlet(new ServletHolder(new CallbackServlet(this)), "/*"); + } + + public int getPort() { + return server.getConnectors()[0].getLocalPort(); + } + + public String getBaseUrl() { + return format("http://localhost:%d/", getPort()); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackServlet.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackServlet.java new file mode 100644 index 00000000..8fcec821 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/CallbackServlet.java @@ -0,0 +1,58 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver.server; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class CallbackServlet extends HttpServlet { + private CallbackHttpServer server; + + CallbackServlet(CallbackHttpServer server) { + this.server = server; + } + + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + if (server.getHttpHandler("GET") != null) { + server.getHttpHandler("GET").call(req, res); + } else { + super.doGet(req, res); + } + } + + protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + if (server.getHttpHandler("POST") != null) { + server.getHttpHandler("POST").call(req, res); + } else { + super.doPost(req, res); + } + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/server/EmptyPageHttpRequestCallback.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/EmptyPageHttpRequestCallback.java new file mode 100644 index 00000000..a3555d01 --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/EmptyPageHttpRequestCallback.java @@ -0,0 +1,40 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver.server; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class EmptyPageHttpRequestCallback implements HttpRequestCallback { + + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + res.getOutputStream().println(""); + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/server/GetFixtureHttpRequestCallback.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/GetFixtureHttpRequestCallback.java new file mode 100644 index 00000000..17121caf --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/GetFixtureHttpRequestCallback.java @@ -0,0 +1,61 @@ +package ghostdriver.server; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; + +public class GetFixtureHttpRequestCallback implements HttpRequestCallback { + + private static final String FIXTURE_PATH = "fixtures"; + + @Override + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException { + String path = req.getPathInfo(); + + if (null != path) { + try { + // Construct path to the file + Path filePath = FileSystems.getDefault().getPath(FIXTURE_PATH, path); + // Set Content Type + res.setContentType(filePathToMimeType(filePath.toString())); + // Read and write to response + Files.copy(filePath, res.getOutputStream()); + + return; + } catch (RuntimeException re) { + // Not Found. Handled below. + } catch (NoSuchFileException nsfe) { + // Not Found. Handled below. + } catch (IOException ioe) { + // Not Found. Handled below. + } + } + + System.out.println("Fixture NOT FOUND"); + res.sendError(404); //< Not Found + } + + private static String filePathToMimeType(String filePath) { + if (filePath.endsWith(".js")) { + return "application/javascript"; + } + if (filePath.endsWith(".json")) { + return "text/json"; + } + if (filePath.endsWith(".png")) { + return "image/png"; + } + if (filePath.endsWith(".jpg")) { + return "image/jpg"; + } + if (filePath.endsWith(".gif")) { + return "image/gif"; + } + + return "text/html"; + } +} diff --git a/test/ghostdriver-test/java/src/test/java/ghostdriver/server/HttpRequestCallback.java b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/HttpRequestCallback.java new file mode 100644 index 00000000..ea5c332e --- /dev/null +++ b/test/ghostdriver-test/java/src/test/java/ghostdriver/server/HttpRequestCallback.java @@ -0,0 +1,36 @@ +/* +This file is part of the GhostDriver by Ivan De Marino . + +Copyright (c) 2014, Ivan De Marino +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package ghostdriver.server; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public interface HttpRequestCallback { + public void call(HttpServletRequest req, HttpServletResponse res) throws IOException; +}