From 35e90e85f5cf46b69f8c1d0afaf5eb3d385e76cd Mon Sep 17 00:00:00 2001 From: Alex Stupakov Date: Fri, 21 Jul 2017 17:57:09 -0700 Subject: [PATCH] Use older version of agouti to make tests pass Signed-off-by: Sam Serrano --- Gopkg.lock | 7 +- Gopkg.toml | 2 +- vendor/github.com/sclevine/agouti/.gitignore | 1 + vendor/github.com/sclevine/agouti/.travis.yml | 3 +- .../sclevine/agouti/CONTRIBUTING.md | 30 +- vendor/github.com/sclevine/agouti/README.md | 8 +- vendor/github.com/sclevine/agouti/agouti.go | 83 +- vendor/github.com/sclevine/agouti/api/api.go | 4 + .../github.com/sclevine/agouti/api/element.go | 57 +- .../sclevine/agouti/api/element_test.go | 275 +++--- .../sclevine/agouti/api/injector_test.go | 5 + .../agouti/api/internal/bus/client.go | 107 +-- .../agouti/api/internal/bus/client_test.go | 133 +-- .../agouti/api/internal/bus/connect.go | 71 ++ .../agouti/api/internal/bus/connect_test.go | 104 +++ .../sclevine/agouti/api/internal/mocks/bus.go | 8 +- .../agouti/api/internal/mocks/service.go | 25 +- .../agouti/api/internal/service/build.go | 42 + .../agouti/api/internal/service/service.go | 64 +- .../api/internal/service/service_test.go | 147 ++-- .../github.com/sclevine/agouti/api/offset.go | 13 + .../github.com/sclevine/agouti/api/session.go | 240 ++++-- .../sclevine/agouti/api/session_test.go | 812 +++++++++++++----- .../github.com/sclevine/agouti/api/speed.go | 32 + .../github.com/sclevine/agouti/api/types.go | 44 + .../sclevine/agouti/api/webdriver.go | 37 +- .../sclevine/agouti/api/webdriver_test.go | 61 +- .../github.com/sclevine/agouti/api/window.go | 8 +- .../sclevine/agouti/api/window_test.go | 42 +- vendor/github.com/sclevine/agouti/cookie.go | 48 -- .../github.com/sclevine/agouti/cookie_test.go | 29 - .../sclevine/agouti/core/capabilities.go | 75 -- .../sclevine/agouti/core/capabilities_test.go | 38 - .../github.com/sclevine/agouti/core/cookie.go | 10 - .../github.com/sclevine/agouti/core/core.go | 86 -- .../sclevine/agouti/core/deprecated.go | 25 - .../core/internal/integration/integration.go | 1 - .../integration/integration_suite_test.go | 25 - .../internal/integration/integration_test.go | 246 ------ .../core/internal/integration/test_page.html | 52 -- .../agouti/core/internal/mocks/bus.go | 23 - .../agouti/core/internal/mocks/element.go | 138 --- .../core/internal/mocks/element_repository.go | 40 - .../agouti/core/internal/mocks/session.go | 319 ------- .../agouti/core/internal/mocks/webdriver.go | 35 - .../agouti/core/internal/page/page.go | 348 -------- .../core/internal/page/page_suite_test.go | 13 - .../agouti/core/internal/page/page_test.go | 549 ------------ .../agouti/core/internal/selection/actions.go | 120 --- .../core/internal/selection/actions_test.go | 297 ------- .../internal/selection/element_repository.go | 133 --- .../selection/element_repository_test.go | 275 ------ .../core/internal/selection/properties.go | 91 -- .../internal/selection/properties_test.go | 233 ----- .../core/internal/selection/selection.go | 94 -- .../selection/selection_suite_test.go | 13 - .../core/internal/selection/selection_test.go | 178 ---- .../core/internal/selection/selector.go | 40 - .../agouti/core/internal/selection/utils.go | 58 -- .../core/internal/selection/utils_test.go | 139 --- .../github.com/sclevine/agouti/core/page.go | 135 --- .../sclevine/agouti/core/selection.go | 151 ---- .../sclevine/agouti/core/user_page.go | 29 - .../sclevine/agouti/core/user_selection.go | 83 -- .../sclevine/agouti/core/webdriver.go | 58 -- .../sclevine/agouti/dsl/deprecated.go | 15 - .../github.com/sclevine/agouti/dsl/driver.go | 69 -- .../sclevine/agouti/dsl/driver_test.go | 137 --- vendor/github.com/sclevine/agouti/dsl/dsl.go | 57 -- .../sclevine/agouti/dsl/failures.go | 28 - .../agouti/dsl/internal/mocks/page.go | 201 ----- .../agouti/dsl/internal/mocks/selection.go | 83 -- vendor/github.com/sclevine/agouti/dsl/page.go | 120 --- .../sclevine/agouti/dsl/page_test.go | 284 ------ .../sclevine/agouti/dsl/selection.go | 52 -- .../sclevine/agouti/dsl/selection_test.go | 135 --- .../sclevine/agouti/injector_test.go | 20 +- .../agouti/internal/element/repository.go | 21 +- .../internal/element/repository_test.go | 226 +++-- .../internal/integration/conflicts_test.go | 16 - .../integration/integration_suite_test.go | 25 +- .../internal/integration/integration_test.go | 322 +------ .../internal/integration/mobile_test.go | 77 ++ .../integration/mobile_test_page.html | 28 + .../agouti/internal/integration/page_test.go | 273 ++++++ .../internal/integration/selection_test.go | 191 ++++ .../internal/integration/test_page.html | 3 + .../agouti/internal/matchers/exactly_equal.go | 31 + .../internal/matchers/exactly_equal_test.go | 27 + .../matchers/matchers_suite_test.go} | 10 +- .../sclevine/agouti/internal/mocks/bus.go | 8 +- .../sclevine/agouti/internal/mocks/element.go | 23 +- .../internal/mocks/element_repository.go | 17 +- .../sclevine/agouti/internal/mocks/session.go | 177 +++- .../agouti/internal/target/selector.go | 53 +- .../agouti/internal/target/selector_test.go | 39 + .../agouti/internal/target/selectors.go | 53 +- .../agouti/internal/target/selectors_test.go | 82 +- .../internal/{selection => }/be_found.go | 11 +- .../internal/{selection => }/be_found_test.go | 12 +- .../matchers/internal/boolean_matcher.go | 36 + ...isible_test.go => boolean_matcher_test.go} | 30 +- .../internal/colorparser/color_parser.go | 294 +++---- .../internal/{selection => }/equal_element.go | 9 +- .../{selection => }/equal_element_test.go | 17 +- .../{selection => }/have_attribute.go | 9 +- .../{selection => }/have_attribute_test.go | 8 +- .../internal/{selection => }/have_css.go | 8 +- .../internal/{selection => }/have_css_test.go | 8 +- .../internal/internal_suite_test.go} | 10 +- .../agouti/matchers/internal/log_matcher.go | 95 ++ .../matchers/internal/log_matcher_test.go | 138 +++ .../internal/{selection => }/match_text.go | 11 +- .../{selection => }/match_text_test.go | 8 +- .../internal/{selection => }/messages.go | 19 +- .../agouti/matchers/internal/mocks/page.go | 13 + .../internal/page/have_logged_error.go | 48 -- .../internal/page/have_logged_error_test.go | 114 --- .../internal/page/have_logged_info.go | 47 - .../internal/page/have_logged_info_test.go | 107 --- .../matchers/internal/page/have_popup_text.go | 38 - .../internal/page/have_popup_text_test.go | 76 -- .../matchers/internal/page/have_title.go | 38 - .../matchers/internal/page/have_title_test.go | 75 -- .../agouti/matchers/internal/page/have_url.go | 38 - .../matchers/internal/page/have_url_test.go | 76 -- .../agouti/matchers/internal/page/messages.go | 16 - .../matchers/internal/page/page_suite_test.go | 13 - .../matchers/internal/selection/be_active.go | 34 - .../internal/selection/be_active_test.go | 74 -- .../matchers/internal/selection/be_enabled.go | 34 - .../internal/selection/be_enabled_test.go | 74 -- .../internal/selection/be_selected.go | 34 - .../internal/selection/be_selected_test.go | 74 -- .../matchers/internal/selection/be_visible.go | 34 - .../matchers/internal/selection/have_text.go | 38 - .../selection/selection_suite_test.go | 13 - .../agouti/matchers/internal/value_matcher.go | 40 + ...ave_text_test.go => value_matcher_test.go} | 18 +- .../sclevine/agouti/matchers/page_matchers.go | 51 +- .../agouti/matchers/page_matchers_test.go | 62 +- .../agouti/matchers/selection_matchers.go | 30 +- .../matchers/selection_matchers_test.go | 52 +- .../sclevine/agouti/multiselection.go | 8 +- .../sclevine/agouti/multiselection_test.go | 35 + vendor/github.com/sclevine/agouti/options.go | 55 +- .../sclevine/agouti/options_test.go | 79 ++ vendor/github.com/sclevine/agouti/page.go | 204 +++-- .../github.com/sclevine/agouti/page_test.go | 360 ++++++-- .../github.com/sclevine/agouti/selectable.go | 90 +- .../sclevine/agouti/selectable_test.go | 129 +++ .../github.com/sclevine/agouti/selection.go | 69 +- .../sclevine/agouti/selection_actions.go | 144 +++- .../sclevine/agouti/selection_actions_test.go | 332 +++++-- .../sclevine/agouti/selection_frames.go | 6 +- .../sclevine/agouti/selection_frames_test.go | 9 +- .../sclevine/agouti/selection_properties.go | 22 +- .../agouti/selection_properties_test.go | 220 +++-- .../sclevine/agouti/selection_test.go | 98 ++- vendor/github.com/sclevine/agouti/types.go | 81 ++ .../github.com/sclevine/agouti/webdriver.go | 60 +- 161 files changed, 5142 insertions(+), 8538 deletions(-) create mode 100644 vendor/github.com/sclevine/agouti/api/injector_test.go create mode 100644 vendor/github.com/sclevine/agouti/api/internal/bus/connect.go create mode 100644 vendor/github.com/sclevine/agouti/api/internal/bus/connect_test.go create mode 100644 vendor/github.com/sclevine/agouti/api/internal/service/build.go create mode 100644 vendor/github.com/sclevine/agouti/api/speed.go create mode 100644 vendor/github.com/sclevine/agouti/api/types.go delete mode 100644 vendor/github.com/sclevine/agouti/cookie.go delete mode 100644 vendor/github.com/sclevine/agouti/cookie_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/capabilities.go delete mode 100644 vendor/github.com/sclevine/agouti/core/capabilities_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/cookie.go delete mode 100644 vendor/github.com/sclevine/agouti/core/core.go delete mode 100644 vendor/github.com/sclevine/agouti/core/deprecated.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/integration/integration.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/integration/integration_suite_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/integration/integration_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/integration/test_page.html delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/mocks/bus.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/mocks/element.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/mocks/element_repository.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/mocks/session.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/mocks/webdriver.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/page/page.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/page/page_suite_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/page/page_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/actions.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/actions_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/element_repository.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/element_repository_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/properties.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/properties_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/selection.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/selection_suite_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/selection_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/selector.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/utils.go delete mode 100644 vendor/github.com/sclevine/agouti/core/internal/selection/utils_test.go delete mode 100644 vendor/github.com/sclevine/agouti/core/page.go delete mode 100644 vendor/github.com/sclevine/agouti/core/selection.go delete mode 100644 vendor/github.com/sclevine/agouti/core/user_page.go delete mode 100644 vendor/github.com/sclevine/agouti/core/user_selection.go delete mode 100644 vendor/github.com/sclevine/agouti/core/webdriver.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/deprecated.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/driver.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/driver_test.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/dsl.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/failures.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/internal/mocks/page.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/internal/mocks/selection.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/page.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/page_test.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/selection.go delete mode 100644 vendor/github.com/sclevine/agouti/dsl/selection_test.go delete mode 100644 vendor/github.com/sclevine/agouti/internal/integration/conflicts_test.go create mode 100644 vendor/github.com/sclevine/agouti/internal/integration/mobile_test.go create mode 100644 vendor/github.com/sclevine/agouti/internal/integration/mobile_test_page.html create mode 100644 vendor/github.com/sclevine/agouti/internal/integration/page_test.go create mode 100644 vendor/github.com/sclevine/agouti/internal/integration/selection_test.go create mode 100644 vendor/github.com/sclevine/agouti/internal/matchers/exactly_equal.go create mode 100644 vendor/github.com/sclevine/agouti/internal/matchers/exactly_equal_test.go rename vendor/github.com/sclevine/agouti/{core/core_suite_test.go => internal/matchers/matchers_suite_test.go} (51%) create mode 100644 vendor/github.com/sclevine/agouti/internal/target/selector_test.go rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/be_found.go (75%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/be_found_test.go (90%) create mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/boolean_matcher.go rename vendor/github.com/sclevine/agouti/matchers/internal/{selection/be_visible_test.go => boolean_matcher_test.go} (59%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/equal_element.go (68%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/equal_element_test.go (78%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/have_attribute.go (69%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/have_attribute_test.go (93%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/have_css.go (87%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/have_css_test.go (94%) rename vendor/github.com/sclevine/agouti/{dsl/dsl_suite_test.go => matchers/internal/internal_suite_test.go} (53%) create mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/log_matcher.go create mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/log_matcher_test.go rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/match_text.go (68%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/match_text_test.go (90%) rename vendor/github.com/sclevine/agouti/matchers/internal/{selection => }/messages.go (57%) delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_logged_error.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_logged_error_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_logged_info.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_logged_info_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_popup_text.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_popup_text_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_title.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_title_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_url.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/have_url_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/messages.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/page/page_suite_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_active.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_active_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_enabled.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_enabled_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_selected.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_selected_test.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/be_visible.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/have_text.go delete mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/selection/selection_suite_test.go create mode 100644 vendor/github.com/sclevine/agouti/matchers/internal/value_matcher.go rename vendor/github.com/sclevine/agouti/matchers/internal/{selection/have_text_test.go => value_matcher_test.go} (77%) create mode 100644 vendor/github.com/sclevine/agouti/multiselection_test.go create mode 100644 vendor/github.com/sclevine/agouti/options_test.go create mode 100644 vendor/github.com/sclevine/agouti/selectable_test.go create mode 100644 vendor/github.com/sclevine/agouti/types.go diff --git a/Gopkg.lock b/Gopkg.lock index 6234ba7..a75a7f0 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -32,9 +32,8 @@ [[projects]] name = "github.com/sclevine/agouti" - packages = [".","api","api/internal/bus","api/internal/service","internal/element","internal/target","matchers","matchers/internal/colorparser","matchers/internal/page","matchers/internal/selection"] - revision = "b920a9cc753368454c642011939e1d7ec58e0024" - version = "2.0" + packages = [".","api","api/internal/bus","api/internal/service","internal/element","internal/target","matchers","matchers/internal","matchers/internal/colorparser"] + revision = "547867f76f1c76d9d5380db4bf27deedd12ec367" [[projects]] branch = "master" @@ -69,6 +68,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "0d9406867c086ca9c0057f65873d196992ca0cd8191175df5c8e21641a91078e" + inputs-digest = "e6f476d8eb20c84b6ee5e89453a6af5af50336ab68abb5a928514b47550b19be" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index f363774..ccd5d24 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -39,7 +39,7 @@ [[constraint]] name = "github.com/sclevine/agouti" - version = "2.0.0" + revision = "547867f76f1c76d9d5380db4bf27deedd12ec367" [[constraint]] branch = "v2" diff --git a/vendor/github.com/sclevine/agouti/.gitignore b/vendor/github.com/sclevine/agouti/.gitignore index 8aeafa5..8512559 100644 --- a/vendor/github.com/sclevine/agouti/.gitignore +++ b/vendor/github.com/sclevine/agouti/.gitignore @@ -2,3 +2,4 @@ .idea *.coverprofile *.test +*.jar \ No newline at end of file diff --git a/vendor/github.com/sclevine/agouti/.travis.yml b/vendor/github.com/sclevine/agouti/.travis.yml index e640df8..7c3f177 100644 --- a/vendor/github.com/sclevine/agouti/.travis.yml +++ b/vendor/github.com/sclevine/agouti/.travis.yml @@ -11,4 +11,5 @@ script: install: - go get -d -t -v ./... && go build -v ./... -env: HEADLESS_ONLY=true +env: + - HEADLESS_ONLY=true diff --git a/vendor/github.com/sclevine/agouti/CONTRIBUTING.md b/vendor/github.com/sclevine/agouti/CONTRIBUTING.md index 6f7859a..df90dd4 100644 --- a/vendor/github.com/sclevine/agouti/CONTRIBUTING.md +++ b/vendor/github.com/sclevine/agouti/CONTRIBUTING.md @@ -1,33 +1,39 @@ # Contributing -## Pull Requests: +## Pull Requests 1. Everything (within reason) must have BDD-style tests. -2. Test driving is very strongly encourage. +2. Test driving (TDD) is very strongly encouraged. 3. Follow all existing patterns and conventions in the codebase. 4. Before issuing a pull-request, please rebase your branch against master. - If you are okay with the maintainer rebasing your pull request, please mention this. -5. After issuing your pull request, check Travis CI to make sure that all tests still pass. + If you are okay with the maintainer rebasing your pull request, please say so. +5. After issuing your pull request, check [Travis CI](https://travis-ci.org/sclevine/agouti) to make sure that all tests still pass. ## Development Setup -* Clone the repository -* Follow the README.md instructions to install Ginkgo, Gomega, PhantomJS, ChromeDriver, and Selenium +* Clone the repository. +* Follow the instructions on agouti.org to install Ginkgo, Gomega, PhantomJS, ChromeDriver, and Selenium. * Run all of the tests using: `ginkgo -r .` * Start developing! ## Method Naming Conventions -### Page or Selection Level +### Agouti package (*Page, *Selection) -* `Name` - Methods that retrieve data or perform some action should not start with "Get", "Is", or "Set". -* `SetName` - Methods that set data and have a corresponding `Name` method should start with "Set". +These are largely context-dependent, but in general: +* `Name` - Methods that do not have a corresponding getter/setter should not start with "Get", "Is", or "Set". +* `GetName` - Non-boolean methods that get data and have a corresponding `SetName` method should start with "Get". +* `IsName` - Boolean methods that get data and have a corresponding `SetName` method should start with "Is". +* `SetName` - Methods that set data and have a corresponding `GetName` method should start with "Set". +* `ReadName` - Methods that exhaust and return data should start with "Read". +* `EnterName` - Methods that enter data without replacing it should start with "Enter". -### API Level +### API package (*Session, *Element, *Window) All API method names should be as close to their endpoint names as possible. * `GetName` for all GET requests returning a non-boolean * `IsName` for all GET requests returning a boolean -* `SetName` for POST requests that have matching GET requests +* `SetName` for POST requests that change the browser state +* `NewNames` for POST requests that return and exhaust some browser state (ex. logs) * `Name` for POST requests that perform some action or retrieve data -* `GetElement` for all POST requests returning an element +* `GetNameElement` for all POST requests returning an element diff --git a/vendor/github.com/sclevine/agouti/README.md b/vendor/github.com/sclevine/agouti/README.md index a379809..047b138 100644 --- a/vendor/github.com/sclevine/agouti/README.md +++ b/vendor/github.com/sclevine/agouti/README.md @@ -4,8 +4,10 @@ Agouti [![Build Status](https://api.travis-ci.org/sclevine/agouti.png?branch=master)](http://travis-ci.org/sclevine/agouti) [![GoDoc](https://godoc.org/github.com/sclevine/agouti?status.svg)](https://godoc.org/github.com/sclevine/agouti) -Acceptance/integration testing for Golang with support for Ginkgo and Gomega! See [agouti.org](http://agouti.org) for more complete documentation. Have questions? Check out the [Agouti mailing list](https://groups.google.com/d/forum/agouti). +[![#agouti IRC on Freenode](https://kiwiirc.com/buttons/chat.freenode.net/agouti.png)](https://kiwiirc.com/client/chat.freenode.net/#agouti) -Want to dive right in? Our [PhantomJS integration test](https://github.com/sclevine/agouti/blob/master/internal/integration/integration_test.go) is a great place to see everything in action. +Agouti is a library for writing browser-based acceptance tests in Google Go. It provides [Gomega](https://github.com/onsi/gomega) matchers and plays nicely with [Ginkgo](https://github.com/onsi/ginkgo). See [agouti.org](http://agouti.org) and the [GoDoc](https://godoc.org/github.com/sclevine/agouti) for documentation. Have questions? Check out the [Agouti mailing list](https://groups.google.com/d/forum/agouti) or the #agouti IRC channel on Freenode. -

+The [integration tests](https://github.com/sclevine/agouti/blob/master/internal/integration/) are a great place to see everything in action and get started quickly! + +

diff --git a/vendor/github.com/sclevine/agouti/agouti.go b/vendor/github.com/sclevine/agouti/agouti.go index c8b6c2f..f49b8f8 100644 --- a/vendor/github.com/sclevine/agouti/agouti.go +++ b/vendor/github.com/sclevine/agouti/agouti.go @@ -1,37 +1,78 @@ // Package agouti is a universal WebDriver client for Go. // It extends the agouti/api package to provide a feature-rich interface for -// controlling a Web Browser. +// controlling a web browser. package agouti import ( "fmt" - - "github.com/sclevine/agouti/api" + "path/filepath" ) -// NewPage opens a Page using the provided WebDriver URL. -func NewPage(url string, options ...Option) (*Page, error) { - desiredCapabilities := getOptions(options).desired - session, err := api.Open(url, desiredCapabilities) +// PhantomJS returns an instance of a PhantomJS WebDriver. +// +// Provided Options will apply as default arguments for new pages. +// New pages will accept invalid SSL certificates by default. This +// may be disabled using the RejectInvalidSSL Option. +// +// The RejectInvalidSSL Option must be provided to the PhantomJS function +// (and not the NewPage method) for this Option to take effect on any +// PhantomJS page. +func PhantomJS(options ...Option) *WebDriver { + command := []string{"phantomjs", "--webdriver={{.Address}}"} + defaultOptions := config{}.Merge(options) + if !defaultOptions.RejectInvalidSSL { + command = append(command, "--ignore-ssl-errors=true") + } + return NewWebDriver("http://{{.Address}}", command, options...) +} + +// ChromeDriver returns an instance of a ChromeDriver WebDriver. +// +// Provided Options will apply as default arguments for new pages. +// New pages will accept invalid SSL certificates by default. This +// may be disabled using the RejectInvalidSSL Option. +func ChromeDriver(options ...Option) *WebDriver { + command := []string{"chromedriver", "--port={{.Port}}"} + return NewWebDriver("http://{{.Address}}", command, options...) +} + +// Selenium returns an instance of a Selenium WebDriver. +// +// Provided Options will apply as default arguments for new pages. +// New pages will accept invalid SSL certificates by default. This +// may be disabled using the RejectInvalidSSL Option. +func Selenium(options ...Option) *WebDriver { + command := []string{"selenium-server", "-port", "{{.Port}}"} + return NewWebDriver("http://{{.Address}}/wd/hub", command, options...) +} + +// Selendroid returns an instance of a Selendroid WebDriver. +// +// Provided Options will apply as default arguments for new pages. +// New pages will accept invalid SSL certificates by default. This +// may be disabled using the RejectInvalidSSL Option. +// +// The jarFile is a relative or absolute path to Selendroid JAR file. +// Selendroid will return nil if an invalid path is provided. +func Selendroid(jarFile string, options ...Option) *WebDriver { + absJARPath, err := filepath.Abs(jarFile) if err != nil { - return nil, fmt.Errorf("failed to connect to WebDriver: %s", err) + return nil + } + + command := []string{ + "java", + "-jar", absJARPath, + "-port", "{{.Port}}", } - return newPage(session), nil + options = append([]Option{Timeout(90), Browser("android")}, options...) + return NewWebDriver("http://{{.Address}}/wd/hub", command, options...) } // SauceLabs opens a Sauce Labs session and returns a *Page. Does not support Sauce Connect. func SauceLabs(name, platform, browser, version, username, accessKey string) (*Page, error) { url := fmt.Sprintf("http://%s:%s@ondemand.saucelabs.com/wd/hub", username, accessKey) - capabilities := Capabilities{ - "name": name, - "platform": platform, - "browserName": browser, - "version": version, - } - - session, err := api.Open(url, capabilities) - if err != nil { - return nil, fmt.Errorf("failed to open connection to Sauce Labs: %s", err) - } - return newPage(session), nil + capabilities := NewCapabilities().Browser(name).Platform(platform).Version(version) + capabilities["name"] = name + return NewPage(url, Desired(capabilities)) } diff --git a/vendor/github.com/sclevine/agouti/api/api.go b/vendor/github.com/sclevine/agouti/api/api.go index 989aa3b..37aaa24 100644 --- a/vendor/github.com/sclevine/agouti/api/api.go +++ b/vendor/github.com/sclevine/agouti/api/api.go @@ -1,4 +1,8 @@ // Package api provides a generic, low-level WebDriver API client for Go. // All methods map directly to endpoints of the WebDriver Wire Protocol: // https://code.google.com/p/selenium/wiki/JsonWireProtocol +// +// This package was previously internal to the agouti package. It currently +// does not have a fixed API, but this will change in the near future +// (with the addition of adequate documentation). package api diff --git a/vendor/github.com/sclevine/agouti/api/element.go b/vendor/github.com/sclevine/agouti/api/element.go index 6d4ce94..7a2368f 100644 --- a/vendor/github.com/sclevine/agouti/api/element.go +++ b/vendor/github.com/sclevine/agouti/api/element.go @@ -1,6 +1,7 @@ package api import ( + "errors" "path" "strings" ) @@ -10,10 +11,14 @@ type Element struct { Session *Session } +func (e *Element) Send(method, endpoint string, body, result interface{}) error { + return e.Session.Send(method, path.Join("element", e.ID, endpoint), body, result) +} + func (e *Element) GetElement(selector Selector) (*Element, error) { var result struct{ Element string } - if err := e.Session.sendElement(e.ID, "element", "POST", selector, &result); err != nil { + if err := e.Send("POST", "element", selector, &result); err != nil { return nil, err } @@ -23,7 +28,7 @@ func (e *Element) GetElement(selector Selector) (*Element, error) { func (e *Element) GetElements(selector Selector) ([]*Element, error) { var results []struct{ Element string } - if err := e.Session.sendElement(e.ID, "elements", "POST", selector, &results); err != nil { + if err := e.Send("POST", "elements", selector, &results); err != nil { return nil, err } @@ -37,15 +42,23 @@ func (e *Element) GetElements(selector Selector) ([]*Element, error) { func (e *Element) GetText() (string, error) { var text string - if err := e.Session.sendElement(e.ID, "text", "GET", nil, &text); err != nil { + if err := e.Send("GET", "text", nil, &text); err != nil { return "", err } return text, nil } +func (e *Element) GetName() (string, error) { + var name string + if err := e.Send("GET", "name", nil, &name); err != nil { + return "", err + } + return name, nil +} + func (e *Element) GetAttribute(attribute string) (string, error) { var value string - if err := e.Session.sendElement(e.ID, path.Join("attribute", attribute), "GET", nil, &value); err != nil { + if err := e.Send("GET", path.Join("attribute", attribute), nil, &value); err != nil { return "", err } return value, nil @@ -53,18 +66,18 @@ func (e *Element) GetAttribute(attribute string) (string, error) { func (e *Element) GetCSS(property string) (string, error) { var value string - if err := e.Session.sendElement(e.ID, path.Join("css", property), "GET", nil, &value); err != nil { + if err := e.Send("GET", path.Join("css", property), nil, &value); err != nil { return "", err } return value, nil } func (e *Element) Click() error { - return e.Session.sendElement(e.ID, "click", "POST", nil) + return e.Send("POST", "click", nil, nil) } func (e *Element) Clear() error { - return e.Session.sendElement(e.ID, "clear", "POST", nil) + return e.Send("POST", "clear", nil, nil) } func (e *Element) Value(text string) error { @@ -72,12 +85,12 @@ func (e *Element) Value(text string) error { request := struct { Value []string `json:"value"` }{splitText} - return e.Session.sendElement(e.ID, "value", "POST", request) + return e.Send("POST", "value", request, nil) } func (e *Element) IsSelected() (bool, error) { var selected bool - if err := e.Session.sendElement(e.ID, "selected", "GET", nil, &selected); err != nil { + if err := e.Send("GET", "selected", nil, &selected); err != nil { return false, err } return selected, nil @@ -85,7 +98,7 @@ func (e *Element) IsSelected() (bool, error) { func (e *Element) IsDisplayed() (bool, error) { var displayed bool - if err := e.Session.sendElement(e.ID, "displayed", "GET", nil, &displayed); err != nil { + if err := e.Send("GET", "displayed", nil, &displayed); err != nil { return false, err } return displayed, nil @@ -93,20 +106,38 @@ func (e *Element) IsDisplayed() (bool, error) { func (e *Element) IsEnabled() (bool, error) { var enabled bool - if err := e.Session.sendElement(e.ID, "enabled", "GET", nil, &enabled); err != nil { + if err := e.Send("GET", "enabled", nil, &enabled); err != nil { return false, err } return enabled, nil } func (e *Element) Submit() error { - return e.Session.sendElement(e.ID, "submit", "POST", nil) + return e.Send("POST", "submit", nil, nil) } func (e *Element) IsEqualTo(other *Element) (bool, error) { + if other == nil { + return false, errors.New("nil element is invalid") + } var equal bool - if err := e.Session.sendElement(e.ID, path.Join("equals", other.ID), "GET", nil, &equal); err != nil { + if err := e.Send("GET", path.Join("equals", other.ID), nil, &equal); err != nil { return false, err } return equal, nil } + +func (e *Element) GetLocation() (x, y int, err error) { + var location struct { + X float64 `json:"x"` + Y float64 `json:"y"` + } + if err := e.Send("GET", "location", nil, &location); err != nil { + return 0, 0, err + } + return round(location.X), round(location.Y), nil +} + +func round(number float64) int { + return int(number + 0.5) +} diff --git a/vendor/github.com/sclevine/agouti/api/element_test.go b/vendor/github.com/sclevine/agouti/api/element_test.go index 7727b46..8342273 100644 --- a/vendor/github.com/sclevine/agouti/api/element_test.go +++ b/vendor/github.com/sclevine/agouti/api/element_test.go @@ -7,14 +7,14 @@ import ( . "github.com/onsi/gomega" . "github.com/sclevine/agouti/api" "github.com/sclevine/agouti/api/internal/mocks" + . "github.com/sclevine/agouti/internal/matchers" ) var _ = Describe("Element", func() { var ( - element *Element - session *Session bus *mocks.Bus - err error + session *Session + element *Element ) BeforeEach(func() { @@ -23,39 +23,45 @@ var _ = Describe("Element", func() { element = &Element{"some-id", session} }) - ItShouldMakeAnElementRequest := func(method, endpoint string, body ...string) { - It("should make a "+method+" request", func() { - Expect(bus.SendCall.Method).To(Equal(method)) + Describe("#Send", func() { + It("should successfully send a request to the provided endpoint", func() { + Expect(element.Send("method", "endpoint", "body", nil)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("method")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/endpoint")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`"body"`)) }) - It("should hit the desired endpoint", func() { - Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/" + endpoint)) - }) - - It("should not return an error", func() { - Expect(err).NotTo(HaveOccurred()) + It("should retrieve the result", func() { + var result string + bus.SendCall.Result = `"some result"` + Expect(element.Send("method", "endpoint", "body", &result)).To(Succeed()) + Expect(result).To(Equal("some result")) }) - if len(body) > 0 { - It("should set the request body", func() { - Expect(bus.SendCall.BodyJSON).To(MatchJSON(body[0])) + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + err := element.Send("method", "endpoint", "body", nil) + Expect(err).To(MatchError("some error")) }) - } - } + }) + }) Describe("#GetElement", func() { - var singleElement *Element - - BeforeEach(func() { - bus.SendCall.Result = `{"ELEMENT": "some-id"}` - singleElement, err = element.GetElement(Selector{"css selector", "#selector"}) + It("should successfully send a POST request to the element endpoint", func() { + _, err := element.GetElement(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/element")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"using": "css selector", "value": "#selector"}`)) }) - ItShouldMakeAnElementRequest("POST", "element", `{"using": "css selector", "value": "#selector"}`) - It("should return an element with an ID and session", func() { + bus.SendCall.Result = `{"ELEMENT": "some-id"}` + singleElement, err := element.GetElement(Selector{}) + Expect(err).NotTo(HaveOccurred()) Expect(singleElement.ID).To(Equal("some-id")) - Expect(singleElement.Session).To(Equal(session)) + Expect(singleElement.Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -68,20 +74,22 @@ var _ = Describe("Element", func() { }) Describe("#GetElements", func() { - var elements []*Element - - BeforeEach(func() { - bus.SendCall.Result = `[{"ELEMENT": "some-id"}, {"ELEMENT": "some-other-id"}]` - elements, err = element.GetElements(Selector{"css selector", "#selector"}) + It("should successfully send a POST request to the elements endpoint", func() { + _, err := element.GetElements(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/elements")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"using": "css selector", "value": "#selector"}`)) }) - ItShouldMakeAnElementRequest("POST", "elements", `{"using": "css selector", "value": "#selector"}`) - It("should return a slice of elements with IDs and sessions", func() { + bus.SendCall.Result = `[{"ELEMENT": "some-id"}, {"ELEMENT": "some-other-id"}]` + elements, err := element.GetElements(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) Expect(elements[0].ID).To(Equal("some-id")) - Expect(elements[0].Session).To(Equal(session)) + Expect(elements[0].Session).To(ExactlyEqual(session)) Expect(elements[1].ID).To(Equal("some-other-id")) - Expect(elements[1].Session).To(Equal(session)) + Expect(elements[1].Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -94,16 +102,17 @@ var _ = Describe("Element", func() { }) Describe("#GetText", func() { - var text string - - BeforeEach(func() { - bus.SendCall.Result = `"some text"` - text, err = element.GetText() + It("should successfully send a GET request to the text endpoint", func() { + _, err := element.GetText() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/text")) }) - ItShouldMakeAnElementRequest("GET", "text") - It("should return the visible text on the element", func() { + bus.SendCall.Result = `"some text"` + text, err := element.GetText() + Expect(err).NotTo(HaveOccurred()) Expect(text).To(Equal("some text")) }) @@ -116,17 +125,42 @@ var _ = Describe("Element", func() { }) }) - Describe("#GetAttribute", func() { - var value string + Describe("#GetName", func() { + It("should successfully send a GET request to the name endpoint", func() { + _, err := element.GetName() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/name")) + }) - BeforeEach(func() { - bus.SendCall.Result = `"some value"` - value, err = element.GetAttribute("some-name") + It("should return the tag name of the element", func() { + bus.SendCall.Result = `"some-name"` + text, err := element.GetName() + Expect(err).NotTo(HaveOccurred()) + Expect(text).To(Equal("some-name")) }) - ItShouldMakeAnElementRequest("GET", "attribute/some-name") + Context("when the bus indicates a failure", func() { + It("should return an error indicating the bus failed to retrieve the tag name", func() { + bus.SendCall.Err = errors.New("some error") + _, err := element.GetName() + Expect(err).To(MatchError("some error")) + }) + }) + }) + + Describe("#GetAttribute", func() { + It("should successfully send a GET request to the attribute/some-name endpoint", func() { + _, err := element.GetAttribute("some-name") + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/attribute/some-name")) + }) It("should return the value of the attribute", func() { + bus.SendCall.Result = `"some value"` + value, err := element.GetAttribute("") + Expect(err).NotTo(HaveOccurred()) Expect(value).To(Equal("some value")) }) @@ -140,16 +174,17 @@ var _ = Describe("Element", func() { }) Describe("#GetCSS", func() { - var value string - - BeforeEach(func() { - bus.SendCall.Result = `"some value"` - value, err = element.GetCSS("some-property") + It("should successfully send a GET request to the css/some-property endpoint", func() { + _, err := element.GetCSS("some-property") + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/css/some-property")) }) - ItShouldMakeAnElementRequest("GET", "css/some-property") - It("should return the value of the CSS property", func() { + bus.SendCall.Result = `"some value"` + value, err := element.GetCSS("some-property") + Expect(err).NotTo(HaveOccurred()) Expect(value).To(Equal("some value")) }) @@ -163,12 +198,12 @@ var _ = Describe("Element", func() { }) Describe("#Click", func() { - BeforeEach(func() { - err = element.Click() + It("should successfully send a POST request to the click endpoint", func() { + Expect(element.Click()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/click")) }) - ItShouldMakeAnElementRequest("POST", "click") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -178,12 +213,12 @@ var _ = Describe("Element", func() { }) Describe("#Clear", func() { - BeforeEach(func() { - err = element.Clear() + It("should successfully send a POST request to the clear endpoint", func() { + Expect(element.Clear()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/clear")) }) - ItShouldMakeAnElementRequest("POST", "clear") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -193,12 +228,13 @@ var _ = Describe("Element", func() { }) Describe("#Value", func() { - BeforeEach(func() { - err = element.Value("text") + It("should successfully send a POST request to the value endpoint", func() { + Expect(element.Value("text")).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/value")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"value": ["t", "e", "x", "t"]}`)) }) - ItShouldMakeAnElementRequest("POST", "value", `{"value": ["t", "e", "x", "t"]}`) - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -208,16 +244,17 @@ var _ = Describe("Element", func() { }) Describe("#IsSelected", func() { - var value bool - - BeforeEach(func() { - bus.SendCall.Result = "true" - value, err = element.IsSelected() + It("should successfully send a GET request to the selected endpoint", func() { + _, err := element.IsSelected() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/selected")) }) - ItShouldMakeAnElementRequest("GET", "selected") - It("should return the selected status", func() { + bus.SendCall.Result = "true" + value, err := element.IsSelected() + Expect(err).NotTo(HaveOccurred()) Expect(value).To(BeTrue()) }) @@ -231,16 +268,17 @@ var _ = Describe("Element", func() { }) Describe("#IsDisplayed", func() { - var value bool - - BeforeEach(func() { - bus.SendCall.Result = "true" - value, err = element.IsDisplayed() + It("should successfully send a GET request to the displayed endpoint", func() { + _, err := element.IsDisplayed() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/displayed")) }) - ItShouldMakeAnElementRequest("GET", "displayed") - It("should return the displayed status", func() { + bus.SendCall.Result = "true" + value, err := element.IsDisplayed() + Expect(err).NotTo(HaveOccurred()) Expect(value).To(BeTrue()) }) @@ -254,16 +292,17 @@ var _ = Describe("Element", func() { }) Describe("#IsEnabled", func() { - var value bool - - BeforeEach(func() { - bus.SendCall.Result = "true" - value, err = element.IsEnabled() + It("should successfully send a GET request to the enabled endpoint", func() { + _, err := element.IsEnabled() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/enabled")) }) - ItShouldMakeAnElementRequest("GET", "enabled") - It("should return the enabled status", func() { + bus.SendCall.Result = "true" + value, err := element.IsEnabled() + Expect(err).NotTo(HaveOccurred()) Expect(value).To(BeTrue()) }) @@ -277,12 +316,12 @@ var _ = Describe("Element", func() { }) Describe("#Submit", func() { - BeforeEach(func() { - err = element.Submit() + It("should successfully send a POST request to the submit endpoint", func() { + Expect(element.Submit()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/submit")) }) - ItShouldMakeAnElementRequest("POST", "submit") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -292,27 +331,57 @@ var _ = Describe("Element", func() { }) Describe("#IsEqualTo", func() { - var ( - equal bool - otherElement *Element - ) - - BeforeEach(func() { - otherElement = &Element{"other-id", session} - bus.SendCall.Result = "true" - equal, err = element.IsEqualTo(otherElement) + It("should successfully send a GET request to the equals/other-id endpoint", func() { + otherElement := &Element{"other-id", session} + _, err := element.IsEqualTo(otherElement) + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/equals/other-id")) }) - ItShouldMakeAnElementRequest("GET", "equals/other-id") - It("should return whether the elements are equal", func() { + bus.SendCall.Result = "true" + equal, err := element.IsEqualTo(&Element{}) + Expect(err).NotTo(HaveOccurred()) Expect(equal).To(BeTrue()) }) + Context("when the other element is nil", func() { + It("should return an error", func() { + _, err := element.IsEqualTo(nil) + Expect(err).To(MatchError("nil element is invalid")) + }) + }) + Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - _, err := element.IsEqualTo(otherElement) + _, err := element.IsEqualTo(&Element{}) + Expect(err).To(MatchError("some error")) + }) + }) + }) + + Describe("#GetLocation", func() { + It("should successfully send a GET request to the location endpoint", func() { + _, _, err := element.GetLocation() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("element/some-id/location")) + }) + + It("should return the rounded location of the element", func() { + bus.SendCall.Result = `{"x": 100.7, "y": 200}` + x, y, err := element.GetLocation() + Expect(err).NotTo(HaveOccurred()) + Expect(x).To(Equal(101)) + Expect(y).To(Equal(200)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error indicating the bus failed to retrieve the location", func() { + bus.SendCall.Err = errors.New("some error") + _, _, err := element.GetLocation() Expect(err).To(MatchError("some error")) }) }) diff --git a/vendor/github.com/sclevine/agouti/api/injector_test.go b/vendor/github.com/sclevine/agouti/api/injector_test.go new file mode 100644 index 0000000..1c67bcb --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/injector_test.go @@ -0,0 +1,5 @@ +package api + +func NewTestWebDriver(service driverService) *WebDriver { + return &WebDriver{service: service} +} diff --git a/vendor/github.com/sclevine/agouti/api/internal/bus/client.go b/vendor/github.com/sclevine/agouti/api/internal/bus/client.go index 1947eb8..f6fdf7d 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/bus/client.go +++ b/vendor/github.com/sclevine/agouti/api/internal/bus/client.go @@ -3,9 +3,7 @@ package bus import ( "bytes" "encoding/json" - "errors" "fmt" - "io" "io/ioutil" "net/http" "strings" @@ -15,95 +13,76 @@ type Client struct { SessionURL string } -func (c *Client) Send(endpoint, method string, body interface{}, result ...interface{}) error { - client := &http.Client{} - - var bodyReader io.Reader - if body != nil { - bodyJSON, err := json.Marshal(body) - if err != nil { - return fmt.Errorf("invalid request body: %s", err) - } - bodyReader = bytes.NewReader(bodyJSON) - } - - requestURL := strings.TrimSuffix(c.SessionURL+"/"+endpoint, "/") - request, err := http.NewRequest(method, requestURL, bodyReader) +func (c *Client) Send(method, endpoint string, body interface{}, result interface{}) error { + requestBody, err := bodyToJSON(body) if err != nil { - return fmt.Errorf("invalid request: %s", err) + return err } - if body != nil { - request.Header.Add("Content-Type", "application/json") - } - - response, err := client.Do(request) + requestURL := strings.TrimSuffix(c.SessionURL+"/"+endpoint, "/") + responseBody, err := makeRequest(requestURL, method, requestBody) if err != nil { - return fmt.Errorf("request failed: %s", err) - } - - responseBody, _ := ioutil.ReadAll(response.Body) - - if response.StatusCode < 200 || response.StatusCode > 299 { - var errBody struct{ Value struct{ Message string } } - if err := json.Unmarshal(responseBody, &errBody); err != nil { - return fmt.Errorf("request unsuccessful: error unreadable") - } - - var errMessage struct{ ErrorMessage string } - if err := json.Unmarshal([]byte(errBody.Value.Message), &errMessage); err != nil { - return fmt.Errorf("request unsuccessful: error message unreadable") - } - - return fmt.Errorf("request unsuccessful: %s", errMessage.ErrorMessage) + return err } - if len(result) > 0 { - bodyValue := struct{ Value interface{} }{result[0]} + if result != nil { + bodyValue := struct{ Value interface{} }{result} if err := json.Unmarshal(responseBody, &bodyValue); err != nil { - return fmt.Errorf("failed to parse response value: %s", err) + return fmt.Errorf("unexpected response: %s", responseBody) } } return nil } -func Connect(url string, capabilities map[string]interface{}) (*Client, error) { - if capabilities == nil { - capabilities = map[string]interface{}{} +func bodyToJSON(body interface{}) ([]byte, error) { + if body == nil { + return nil, nil } - desiredCapabilities := struct { - DesiredCapabilities map[string]interface{} `json:"desiredCapabilities"` - }{capabilities} - - capabiltiesJSON, err := json.Marshal(desiredCapabilities) + bodyJSON, err := json.Marshal(body) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid request body: %s", err) } + return bodyJSON, nil +} - postBody := strings.NewReader(string(capabiltiesJSON)) - request, err := http.NewRequest("POST", fmt.Sprintf("%s/session", url), postBody) +func makeRequest(url, method string, body []byte) ([]byte, error) { + request, err := http.NewRequest(method, url, bytes.NewReader(body)) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid request: %s", err) } - request.Header.Add("Content-Type", "application/json") + if body != nil { + request.Header.Add("Content-Type", "application/json") + } - client := &http.Client{} - response, err := client.Do(request) + response, err := http.DefaultClient.Do(request) + if err != nil { + return nil, fmt.Errorf("request failed: %s", err) + } + + responseBody, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err } - var sessionResponse struct{ SessionID string } + if response.StatusCode < 200 || response.StatusCode > 299 { + return nil, parseResponseError(responseBody) + } + + return responseBody, nil +} - body, _ := ioutil.ReadAll(response.Body) - json.Unmarshal(body, &sessionResponse) +func parseResponseError(body []byte) error { + var errBody struct{ Value struct{ Message string } } + if err := json.Unmarshal(body, &errBody); err != nil { + return fmt.Errorf("request unsuccessful: %s", body) + } - if sessionResponse.SessionID == "" { - return nil, errors.New("failed to retrieve a session ID") + var errMessage struct{ ErrorMessage string } + if err := json.Unmarshal([]byte(errBody.Value.Message), &errMessage); err != nil { + return fmt.Errorf("request unsuccessful: %s", errBody.Value.Message) } - sessionURL := fmt.Sprintf("%s/session/%s", url, sessionResponse.SessionID) - return &Client{sessionURL}, nil + return fmt.Errorf("request unsuccessful: %s", errMessage.ErrorMessage) } diff --git a/vendor/github.com/sclevine/agouti/api/internal/bus/client_test.go b/vendor/github.com/sclevine/agouti/api/internal/bus/client_test.go index 8a78dc5..376126a 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/bus/client_test.go +++ b/vendor/github.com/sclevine/agouti/api/internal/bus/client_test.go @@ -22,6 +22,8 @@ var _ = Describe("Session", func() { ) BeforeEach(func() { + responseBody, responseStatus = "", 200 + requestPath, requestMethod, requestBody, requestContentType = "", "", "", "" server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { requestPath = request.URL.Path requestMethod = request.Method @@ -31,8 +33,6 @@ var _ = Describe("Session", func() { response.WriteHeader(responseStatus) response.Write([]byte(responseBody)) })) - - responseStatus = 200 }) AfterEach(func() { @@ -46,47 +46,38 @@ var _ = Describe("Session", func() { client = &Client{SessionURL: server.URL + "/session/some-id"} }) + It("should make a request with the method and full session endpoint", func() { + client.Send("GET", "some/endpoint", nil, nil) + Expect(requestPath).To(Equal("/session/some-id/some/endpoint")) + Expect(requestMethod).To(Equal("GET")) + }) + Context("with a valid request body", func() { - It("should make a request with the provided body", func() { + It("should make a application/json request with the provided body", func() { body := struct{ SomeValue string }{"some request value"} - client.Send("some/endpoint", "POST", body) + Expect(client.Send("POST", "some/endpoint", body, nil)).To(Succeed()) Expect(requestBody).To(Equal(`{"SomeValue":"some request value"}`)) - }) - - It("should make a request with content type application/json", func() { - body := struct{ SomeValue string }{"some request value"} - client.Send("some/endpoint", "POST", body) Expect(requestContentType).To(Equal("application/json")) }) }) Context("with an invalid request body", func() { It("should return an invalid request body error", func() { - err := client.Send("some/endpoint", "POST", func() {}) + err := client.Send("POST", "some/endpoint", func() {}, nil) Expect(err).To(MatchError("invalid request body: json: unsupported type: func()")) }) }) Context("when the provided body is nil", func() { It("should make a request without a body", func() { - Expect(client.Send("some/endpoint", "POST", nil)).To(Succeed()) + Expect(client.Send("POST", "some/endpoint", nil, nil)).To(Succeed()) Expect(requestBody).To(BeEmpty()) }) }) - It("should make a request with the full session endpoint", func() { - client.Send("some/endpoint", "GET", nil) - Expect(requestPath).To(Equal("/session/some-id/some/endpoint")) - }) - - It("should make a request with the given method", func() { - client.Send("some/endpoint", "GET", nil) - Expect(requestMethod).To(Equal("GET")) - }) - Context("when the session endpoint is empty", func() { It("should make a request to the session itself", func() { - client.Send("", "GET", nil) + Expect(client.Send("GET", "", nil, nil)).To(Succeed()) Expect(requestPath).To(Equal("/session/some-id")) }) }) @@ -94,7 +85,7 @@ var _ = Describe("Session", func() { Context("with an invalid URL", func() { It("should return an invalid request error", func() { client.SessionURL = "%@#$%" - err := client.Send("some/endpoint", "GET", nil) + err := client.Send("GET", "some/endpoint", nil, nil) Expect(err).To(MatchError(`invalid request: parse %@: invalid URL escape "%@"`)) }) }) @@ -102,36 +93,37 @@ var _ = Describe("Session", func() { Context("when the request fails entirely", func() { It("should return an error indicating that the request failed", func() { server.Close() - err := client.Send("some/endpoint", "GET", nil) + err := client.Send("GET", "some/endpoint", nil, nil) Expect(err.Error()).To(MatchRegexp("request failed: .+ connection refused")) }) }) Context("when the server responds with a non-2xx status code", func() { + BeforeEach(func() { + responseStatus = 400 + }) + Context("when the server has a valid error message", func() { It("should return an error from the server indicating that the request failed", func() { - responseStatus = 400 responseBody = `{"value": {"message": "{\"errorMessage\": \"some error\"}"}}` - err := client.Send("some/endpoint", "GET", nil) + err := client.Send("GET", "some/endpoint", nil, nil) Expect(err).To(MatchError("request unsuccessful: some error")) }) }) Context("when the server does not have a valid message", func() { - It("should return an error from the server indicating that the request failed", func() { - responseStatus = 400 - responseBody = `{}}` - err := client.Send("some/endpoint", "GET", nil) - Expect(err).To(MatchError("request unsuccessful: error unreadable")) + It("should return an error indicating that the request failed with no details", func() { + responseBody = `$$$` + err := client.Send("GET", "some/endpoint", nil, nil) + Expect(err).To(MatchError("request unsuccessful: $$$")) }) }) - Context("when the server does not have a valid error message", func() { - It("should return an error from the server indicating that the request failed", func() { - responseStatus = 400 - responseBody = `{"value": {"message": "{}}"}}` - err := client.Send("some/endpoint", "GET", nil) - Expect(err).To(MatchError("request unsuccessful: error message unreadable")) + Context("when the server does not have a valid JSON-encoded error message", func() { + It("should return an error with the entire message output", func() { + responseBody = `{"value": {"message": "$$$"}}` + err := client.Send("GET", "some/endpoint", nil, nil) + Expect(err).To(MatchError("request unsuccessful: $$$")) }) }) }) @@ -144,76 +136,19 @@ var _ = Describe("Session", func() { }) Context("with a valid response body", func() { - It("should successfully unmashal the returned JSON into the result, if provided", func() { - Expect(client.Send("some/endpoint", "GET", nil, &result)).To(Succeed()) + It("should successfully unmarshal the returned JSON into the result", func() { + Expect(client.Send("GET", "some/endpoint", nil, &result)).To(Succeed()) Expect(result.Some).To(Equal("response value")) }) }) Context("with a response body value that cannot be read", func() { It("should return a failed to extract value from response error", func() { - responseBody = `{"value": "unexpected string"}` - err := client.Send("some/endpoint", "GET", nil, &result) - Expect(err).To(MatchError("failed to parse response value: json: cannot unmarshal string into Go value of type struct { Some string }")) + responseBody = "some unexpected response" + err := client.Send("GET", "some/endpoint", nil, &result) + Expect(err).To(MatchError("unexpected response: some unexpected response")) }) }) }) }) - - Describe(".Connect", func() { - It("should make a POST request with the provided desired capabilities", func() { - Connect(server.URL, map[string]interface{}{"some": "json"}) - Expect(requestBody).To(MatchJSON(`{"desiredCapabilities": {"some": "json"}}`)) - }) - - It("should make the request with content type application/json", func() { - Connect(server.URL, map[string]interface{}{"some": "json"}) - Expect(requestContentType).To(Equal("application/json")) - }) - - Context("when the capabilities are invalid", func() { - It("should return an error", func() { - _, err := Connect(server.URL, map[string]interface{}{"some": func() {}}) - Expect(err).To(MatchError("json: unsupported type: func()")) - }) - }) - - Context("when the capabilities are nil", func() { - It("should make a POST request with empty capabilities", func() { - Connect(server.URL, nil) - Expect(requestBody).To(MatchJSON(`{"desiredCapabilities": {}}`)) - }) - }) - - Context("when the request is invalid", func() { - It("should return the invalid request error", func() { - _, err := Connect("%@#$%", map[string]interface{}{"some": "json"}) - Expect(err.Error()).To(ContainSubstring(`parse %@: invalid URL escape "%@"`)) - }) - }) - - Context("when the request fails", func() { - It("should return the failed request error", func() { - _, err := Connect("http://#", map[string]interface{}{"some": "json"}) - Expect(err.Error()).To(ContainSubstring("Post http://#/session")) - }) - }) - - Context("if the request does not contain a session ID", func() { - It("should return an error indicating that it failed to receive a session ID", func() { - responseBody = "{}" - _, err := Connect(server.URL, map[string]interface{}{"some": "json"}) - Expect(err).To(MatchError("failed to retrieve a session ID")) - }) - }) - - Context("if the request succeeds", func() { - It("should return a session with session URL", func() { - responseBody = `{"sessionId": "some-id"}` - client, err := Connect(server.URL, map[string]interface{}{"some": "json"}) - Expect(err).NotTo(HaveOccurred()) - Expect(client.SessionURL).To(ContainSubstring("/session/some-id")) - }) - }) - }) }) diff --git a/vendor/github.com/sclevine/agouti/api/internal/bus/connect.go b/vendor/github.com/sclevine/agouti/api/internal/bus/connect.go new file mode 100644 index 0000000..d6dd900 --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/internal/bus/connect.go @@ -0,0 +1,71 @@ +package bus + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" +) + +func Connect(url string, capabilities map[string]interface{}) (*Client, error) { + requestBody, err := capabilitiesToJSON(capabilities) + if err != nil { + return nil, err + } + + sessionID, err := openSession(url, requestBody) + if err != nil { + return nil, err + } + + sessionURL := fmt.Sprintf("%s/session/%s", url, sessionID) + return &Client{sessionURL}, nil +} + +func capabilitiesToJSON(capabilities map[string]interface{}) (io.Reader, error) { + if capabilities == nil { + capabilities = map[string]interface{}{} + } + desiredCapabilities := struct { + DesiredCapabilities map[string]interface{} `json:"desiredCapabilities"` + }{capabilities} + + capabiltiesJSON, err := json.Marshal(desiredCapabilities) + if err != nil { + return nil, err + } + return bytes.NewReader(capabiltiesJSON), err +} + +func openSession(url string, body io.Reader) (sessionID string, err error) { + request, err := http.NewRequest("POST", fmt.Sprintf("%s/session", url), body) + if err != nil { + return "", err + } + + request.Header.Add("Content-Type", "application/json") + + response, err := http.DefaultClient.Do(request) + if err != nil { + return "", err + } + + var sessionResponse struct{ SessionID string } + responseBody, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", err + } + + if err := json.Unmarshal(responseBody, &sessionResponse); err != nil { + return "", err + } + + if sessionResponse.SessionID == "" { + return "", errors.New("failed to retrieve a session ID") + } + + return sessionResponse.SessionID, nil +} diff --git a/vendor/github.com/sclevine/agouti/api/internal/bus/connect_test.go b/vendor/github.com/sclevine/agouti/api/internal/bus/connect_test.go new file mode 100644 index 0000000..b0290e5 --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/internal/bus/connect_test.go @@ -0,0 +1,104 @@ +package bus_test + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/sclevine/agouti/api/internal/bus" +) + +var _ = Describe(".Connect", func() { + var ( + requestPath string + requestMethod string + requestBody string + requestContentType string + responseBody string + server *httptest.Server + ) + + BeforeEach(func() { + responseBody = `{"sessionId": "some-id"}` + requestPath, requestMethod, requestBody, requestContentType = "", "", "", "" + server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { + requestPath = request.URL.Path // TODO: use + requestMethod = request.Method + requestBodyBytes, _ := ioutil.ReadAll(request.Body) + requestBody = string(requestBodyBytes) + requestContentType = request.Header.Get("Content-Type") + response.Write([]byte(responseBody)) + })) + }) + + AfterEach(func() { + server.Close() + }) + + It("should successfully make an application/json POST request to the session endpoint", func() { + _, err := Connect(server.URL, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(requestMethod).To(Equal("POST")) + Expect(requestPath).To(Equal("/session")) + Expect(requestContentType).To(Equal("application/json")) + }) + + It("should return a client with a session URL", func() { + client, err := Connect(server.URL, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(client.SessionURL).To(ContainSubstring("/session/some-id")) + }) + + It("should make the request with the provided desired capabilities", func() { + _, err := Connect(server.URL, map[string]interface{}{"some": "json"}) + Expect(err).NotTo(HaveOccurred()) + Expect(requestBody).To(MatchJSON(`{"desiredCapabilities": {"some": "json"}}`)) + }) + + Context("when the capabilities are nil", func() { + It("should make the request with empty capabilities", func() { + _, err := Connect(server.URL, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(requestBody).To(MatchJSON(`{"desiredCapabilities": {}}`)) + }) + }) + + Context("when the capabilities are invalid", func() { + It("should return an error", func() { + _, err := Connect(server.URL, map[string]interface{}{"some": func() {}}) + Expect(err).To(MatchError("json: unsupported type: func()")) + }) + }) + + Context("when the request is invalid", func() { + It("should return an error", func() { + _, err := Connect("%@#$%", nil) + Expect(err.Error()).To(ContainSubstring(`parse %@: invalid URL escape "%@"`)) + }) + }) + + Context("when the request fails", func() { + It("should return an error", func() { + _, err := Connect("http://#", nil) + Expect(err.Error()).To(ContainSubstring("Post http://#/session")) + }) + }) + + Context("when the response contains invalid JSON", func() { + It("should return an error", func() { + responseBody = "$$$" + _, err := Connect(server.URL, nil) + Expect(err).To(MatchError("invalid character '$' looking for beginning of value")) + }) + }) + + Context("when the response does not contain a session ID", func() { + It("should return an error", func() { + responseBody = "{}" + _, err := Connect(server.URL, nil) + Expect(err).To(MatchError("failed to retrieve a session ID")) + }) + }) +}) diff --git a/vendor/github.com/sclevine/agouti/api/internal/mocks/bus.go b/vendor/github.com/sclevine/agouti/api/internal/mocks/bus.go index 1cdd15e..b94122f 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/mocks/bus.go +++ b/vendor/github.com/sclevine/agouti/api/internal/mocks/bus.go @@ -12,12 +12,12 @@ type Bus struct { } } -func (b *Bus) Send(endpoint, method string, body interface{}, result ...interface{}) error { - b.SendCall.Endpoint = endpoint +func (b *Bus) Send(method, endpoint string, body, result interface{}) error { b.SendCall.Method = method + b.SendCall.Endpoint = endpoint b.SendCall.BodyJSON, _ = json.Marshal(body) - if len(result) > 0 { - json.Unmarshal([]byte(b.SendCall.Result), result[0]) + if result != nil { + json.Unmarshal([]byte(b.SendCall.Result), result) } return b.SendCall.Err } diff --git a/vendor/github.com/sclevine/agouti/api/internal/mocks/service.go b/vendor/github.com/sclevine/agouti/api/internal/mocks/service.go index baa27bb..6f50c9c 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/mocks/service.go +++ b/vendor/github.com/sclevine/agouti/api/internal/mocks/service.go @@ -5,26 +5,32 @@ import "time" type Service struct { URLCall struct { ReturnURL string - Err error } StartCall struct { - Timeout time.Duration - Err error + Debug bool + Called bool + Err error } StopCall struct { Called bool Err error } + + WaitForBootCall struct { + Timeout time.Duration + Err error + } } -func (s *Service) URL() (string, error) { - return s.URLCall.ReturnURL, s.URLCall.Err +func (s *Service) URL() string { + return s.URLCall.ReturnURL } -func (s *Service) Start(timeout time.Duration) error { - s.StartCall.Timeout = timeout +func (s *Service) Start(debug bool) error { + s.StartCall.Debug = debug + s.StartCall.Called = true return s.StartCall.Err } @@ -32,3 +38,8 @@ func (s *Service) Stop() error { s.StopCall.Called = true return s.StopCall.Err } + +func (s *Service) WaitForBoot(timeout time.Duration) error { + s.WaitForBootCall.Timeout = timeout + return s.WaitForBootCall.Err +} diff --git a/vendor/github.com/sclevine/agouti/api/internal/service/build.go b/vendor/github.com/sclevine/agouti/api/internal/service/build.go new file mode 100644 index 0000000..017208a --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/internal/service/build.go @@ -0,0 +1,42 @@ +package service + +import ( + "bytes" + "errors" + "os/exec" + "text/template" +) + +func buildURL(url string, address addressInfo) (string, error) { + urlTemplate, err := template.New("URL").Parse(url) + if err != nil { + return "", err + } + urlBuffer := &bytes.Buffer{} + if err := urlTemplate.Execute(urlBuffer, address); err != nil { + return "", err + } + return urlBuffer.String(), nil +} + +func buildCommand(arguments []string, address addressInfo) (*exec.Cmd, error) { + if len(arguments) == 0 { + return nil, errors.New("empty command") + } + + command := []string{} + for _, argument := range arguments { + argTemplate, err := template.New("command").Parse(argument) + if err != nil { + return nil, err + } + + argBuffer := &bytes.Buffer{} + if err := argTemplate.Execute(argBuffer, address); err != nil { + return nil, err + } + command = append(command, argBuffer.String()) + } + + return exec.Command(command[0], command[1:]...), nil +} diff --git a/vendor/github.com/sclevine/agouti/api/internal/service/service.go b/vendor/github.com/sclevine/agouti/api/internal/service/service.go index aa0651c..1d7e458 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/service/service.go +++ b/vendor/github.com/sclevine/agouti/api/internal/service/service.go @@ -1,16 +1,15 @@ package service import ( - "bytes" "errors" "fmt" "net" "net/http" + "os" "os/exec" "runtime" "strings" "syscall" - "text/template" "time" ) @@ -27,15 +26,11 @@ type addressInfo struct { Port string } -func (s *Service) URL() (string, error) { - if s.command == nil { - return "", errors.New("not running") - } - - return s.url, nil +func (s *Service) URL() string { + return s.url } -func (s *Service) Start(timeout time.Duration) error { +func (s *Service) Start(debug bool) error { if s.command != nil { return errors.New("already running") } @@ -45,7 +40,8 @@ func (s *Service) Start(timeout time.Duration) error { return fmt.Errorf("failed to locate a free port: %s", err) } - if s.url, err = buildURL(s.URLTemplate, address); err != nil { + url, err := buildURL(s.URLTemplate, address) + if err != nil { return fmt.Errorf("failed to parse URL: %s", err) } @@ -54,13 +50,19 @@ func (s *Service) Start(timeout time.Duration) error { return fmt.Errorf("failed to parse command: %s", err) } + if debug { + command.Stdout = os.Stdout + command.Stderr = os.Stderr + } + if err := command.Start(); err != nil { return fmt.Errorf("failed to run command: %s", err) } s.command = command + s.url = url - return s.waitForServer(timeout) + return nil } func (s *Service) Stop() error { @@ -72,7 +74,7 @@ func (s *Service) Stop() error { if runtime.GOOS == "windows" { err = s.command.Process.Kill() } else { - err = s.command.Process.Signal(syscall.SIGINT) + err = s.command.Process.Signal(syscall.SIGTERM) } if err != nil { return fmt.Errorf("failed to stop command: %s", err) @@ -80,44 +82,11 @@ func (s *Service) Stop() error { s.command.Wait() s.command = nil + s.url = "" return nil } -func buildURL(url string, address addressInfo) (string, error) { - urlTemplate, err := template.New("URL").Parse(url) - if err != nil { - return "", err - } - urlBuffer := &bytes.Buffer{} - if err := urlTemplate.Execute(urlBuffer, address); err != nil { - return "", err - } - return urlBuffer.String(), nil -} - -func buildCommand(arguments []string, address addressInfo) (*exec.Cmd, error) { - if len(arguments) == 0 { - return nil, errors.New("empty command") - } - - command := []string{} - for _, argument := range arguments { - argTemplate, err := template.New("command").Parse(argument) - if err != nil { - return nil, err - } - - argBuffer := &bytes.Buffer{} - if err := argTemplate.Execute(argBuffer, address); err != nil { - return nil, err - } - command = append(command, argBuffer.String()) - } - - return exec.Command(command[0], command[1:]...), nil -} - func freeAddress() (addressInfo, error) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { @@ -130,7 +99,7 @@ func freeAddress() (addressInfo, error) { return addressInfo{address, addressParts[0], addressParts[1]}, nil } -func (s *Service) waitForServer(timeout time.Duration) error { +func (s *Service) WaitForBoot(timeout time.Duration) error { timeoutChan := time.After(timeout) failedChan := make(chan struct{}, 1) startedChan := make(chan struct{}) @@ -152,7 +121,6 @@ func (s *Service) waitForServer(timeout time.Duration) error { select { case <-timeoutChan: failedChan <- struct{}{} - s.Stop() return errors.New("failed to start before timeout") case <-startedChan: return nil diff --git a/vendor/github.com/sclevine/agouti/api/internal/service/service_test.go b/vendor/github.com/sclevine/agouti/api/internal/service/service_test.go index 4591581..eb28dfe 100644 --- a/vendor/github.com/sclevine/agouti/api/internal/service/service_test.go +++ b/vendor/github.com/sclevine/agouti/api/internal/service/service_test.go @@ -11,48 +11,30 @@ import ( ) var _ = Describe("Service", func() { - const testTimeout = 1500 * time.Millisecond - var ( - service *Service - started bool - server *httptest.Server - ) + var service *Service BeforeEach(func() { - started = false - - server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { - if started && request.URL.Path == "/status" { - response.WriteHeader(200) - } else { - response.WriteHeader(400) - } - })) - service = &Service{ - URLTemplate: server.URL, + URLTemplate: "some-url", CmdTemplate: []string{"true"}, } }) - AfterEach(func() { - server.Close() - }) - Describe("#URL", func() { Context("when the server is not running", func() { - It("should return an error", func() { - _, err := service.URL() - Expect(err).To(MatchError("not running")) + It("should return an empty string", func() { + Expect(service.URL()).To(BeEmpty()) + Expect(service.Start(false)).To(Succeed()) + Expect(service.Stop()).To(Succeed()) + Expect(service.URL()).To(BeEmpty()) }) }) Context("when the server is running", func() { It("should successfully return the URL", func() { defer service.Stop() - started = true - service.Start(testTimeout) - Expect(service.URL()).To(MatchRegexp(`http://127.0.0.1:\d+`)) + Expect(service.Start(false)).To(Succeed()) + Expect(service.URL()).To(MatchRegexp("some-url")) }) }) }) @@ -61,47 +43,31 @@ var _ = Describe("Service", func() { Context("when the service is started multiple times", func() { It("should return an error indicating that service is already running", func() { defer service.Stop() - started = true - Expect(service.Start(testTimeout)).To(Succeed()) - Expect(service.Start(testTimeout)).To(MatchError("already running")) + Expect(service.Start(false)).To(Succeed()) + Expect(service.Start(false)).To(MatchError("already running")) }) }) Context("when the binary is not available in PATH", func() { It("should return an error indicating the binary needs to be installed", func() { service.CmdTemplate = []string{"not-in-path"} - Expect(service.Start(testTimeout)).To(MatchError("failed to run command: exec: \"not-in-path\": executable file not found in $PATH")) - }) - }) - - Context("when the service does not start before the provided timeout", func() { - It("should return an error", func() { - defer service.Stop() - go func() { - time.Sleep(3000 * time.Millisecond) - started = true - }() - Expect(service.Start(testTimeout)).To(MatchError("failed to start before timeout")) + Expect(service.Start(false)).To(MatchError("failed to run command: exec: \"not-in-path\": executable file not found in $PATH")) }) }) - Context("when the service starts before the provided timeout", func() { - It("should not return an error", func() { + Context("when the service is started in debug mode", func() { + It("should successfully start", func() { defer service.Stop() - go func() { - time.Sleep(200 * time.Millisecond) - started = true - }() - Expect(service.Start(testTimeout)).To(Succeed()) + Expect(service.Start(true)).To(Succeed()) }) }) - Context("when provided with a templated URL", func() { + Describe("the provided templated URL", func() { Context("when the template is invalid", func() { It("should return an error", func() { defer service.Stop() service.URLTemplate = "{{}}" - Expect(service.Start(testTimeout)).To(MatchError("failed to parse URL: template: URL:1: missing value for command")) + Expect(service.Start(false)).To(MatchError("failed to parse URL: template: URL:1: missing value for command")) }) }) @@ -109,28 +75,26 @@ var _ = Describe("Service", func() { It("should return an error", func() { defer service.Stop() service.URLTemplate = "{{.Bad}}" - Expect(service.Start(testTimeout)).To(MatchError("failed to parse URL: template: URL:1:2: executing \"URL\" at <.Bad>: Bad is not a field of struct type service.addressInfo")) + Expect(service.Start(false)).To(MatchError("failed to parse URL: template: URL:1:2: executing \"URL\" at <.Bad>: Bad is not a field of struct type service.addressInfo")) }) }) Context("when the template is valid", func() { It("should store a templated URL", func() { defer service.Stop() - started = true service.URLTemplate += "/status?test&{{.Address}}&{{.Host}}:{{.Port}}" - service.Start(testTimeout) - url, _ := service.URL() - Expect(url).To(MatchRegexp(`test&127\.0\.0\.1:\d+&127\.0\.0\.1:\d+`)) + service.Start(false) + Expect(service.URL()).To(MatchRegexp(`test&127\.0\.0\.1:\d+&127\.0\.0\.1:\d+`)) }) }) }) - Context("when provided with a templated command", func() { + Describe("the provided templated command", func() { Context("when the template is invalid", func() { It("should return an error", func() { defer service.Stop() service.CmdTemplate = []string{"correct", "{{}}"} - Expect(service.Start(testTimeout)).To(MatchError("failed to parse command: template: command:1: missing value for command")) + Expect(service.Start(false)).To(MatchError("failed to parse command: template: command:1: missing value for command")) }) }) @@ -138,16 +102,23 @@ var _ = Describe("Service", func() { It("should return an error", func() { defer service.Stop() service.CmdTemplate = []string{"correct", "{{.Bad}}"} - Expect(service.Start(testTimeout)).To(MatchError("failed to parse command: template: command:1:2: executing \"command\" at <.Bad>: Bad is not a field of struct type service.addressInfo")) + Expect(service.Start(false)).To(MatchError("failed to parse command: template: command:1:2: executing \"command\" at <.Bad>: Bad is not a field of struct type service.addressInfo")) + }) + }) + + Context("when the template is empty", func() { + It("should return an error", func() { + defer service.Stop() + service.CmdTemplate = []string{} + Expect(service.Start(false)).To(MatchError("failed to parse command: empty command")) }) }) Context("when the template is valid", func() { It("should not return an error", func() { defer service.Stop() - started = true service.CmdTemplate = []string{"true", "{{.Address}}{{.Host}}{{.Port}}"} - Expect(service.Start(testTimeout)).To(Succeed()) + Expect(service.Start(false)).To(Succeed()) }) }) }) @@ -156,10 +127,9 @@ var _ = Describe("Service", func() { Describe("#Stop", func() { It("should stop a running server", func() { defer service.Stop() - started = true - Expect(service.Start(testTimeout)).To(Succeed()) + Expect(service.Start(false)).To(Succeed()) Expect(service.Stop()).To(Succeed()) - Expect(service.Start(testTimeout)).To(Succeed()) + Expect(service.Start(false)).To(Succeed()) }) Context("when the command is not started", func() { @@ -169,4 +139,53 @@ var _ = Describe("Service", func() { }) }) }) + + Describe("#WaitForBoot", func() { + var ( + started bool + server *httptest.Server + ) + + BeforeEach(func() { + started = false + + server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { + if started && request.URL.Path == "/status" { + response.WriteHeader(200) + } else { + response.WriteHeader(400) + } + })) + + service.URLTemplate = server.URL + }) + + AfterEach(func() { + server.Close() + }) + + Context("when the service does not start before the provided timeout", func() { + It("should return an error", func() { + defer service.Stop() + go func() { + time.Sleep(3000 * time.Millisecond) + started = true + }() + Expect(service.Start(false)).To(Succeed()) + Expect(service.WaitForBoot(1500 * time.Millisecond)).To(MatchError("failed to start before timeout")) + }) + }) + + Context("when the service starts before the provided timeout", func() { + It("should not return an error", func() { + defer service.Stop() + go func() { + time.Sleep(200 * time.Millisecond) + started = true + }() + Expect(service.Start(false)).To(Succeed()) + Expect(service.WaitForBoot(1500 * time.Millisecond)).To(Succeed()) + }) + }) + }) }) diff --git a/vendor/github.com/sclevine/agouti/api/offset.go b/vendor/github.com/sclevine/agouti/api/offset.go index 9f731c5..c98afa5 100644 --- a/vendor/github.com/sclevine/agouti/api/offset.go +++ b/vendor/github.com/sclevine/agouti/api/offset.go @@ -3,6 +3,7 @@ package api type Offset interface { x() (x int, present bool) y() (y int, present bool) + position() (x int, y int) } type XYOffset struct { @@ -18,6 +19,10 @@ func (o XYOffset) y() (y int, present bool) { return o.Y, true } +func (o XYOffset) position() (x int, y int) { + return o.X, o.Y +} + type XOffset int func (o XOffset) x() (x int, present bool) { @@ -28,6 +33,10 @@ func (XOffset) y() (y int, present bool) { return 0, false } +func (o XOffset) position() (x int, y int) { + return int(o), 0 +} + type YOffset int func (YOffset) x() (x int, present bool) { @@ -37,3 +46,7 @@ func (YOffset) x() (x int, present bool) { func (o YOffset) y() (y int, present bool) { return int(o), true } + +func (o YOffset) position() (x int, y int) { + return 0, int(o) +} diff --git a/vendor/github.com/sclevine/agouti/api/session.go b/vendor/github.com/sclevine/agouti/api/session.go index a962bb3..24b605f 100644 --- a/vendor/github.com/sclevine/agouti/api/session.go +++ b/vendor/github.com/sclevine/agouti/api/session.go @@ -2,28 +2,17 @@ package api import ( "encoding/base64" - "path" + "errors" "github.com/sclevine/agouti/api/internal/bus" ) -type Log struct { - Message string - Level string - Timestamp int64 -} - -type Selector struct { - Using string `json:"using"` - Value string `json:"value"` -} - type Session struct { - Bus busSender + Bus } -type busSender interface { - Send(endpoint, method string, body interface{}, result ...interface{}) error +type Bus interface { + Send(method, endpoint string, body, result interface{}) error } func Open(url string, capabilities map[string]interface{}) (*Session, error) { @@ -35,13 +24,13 @@ func Open(url string, capabilities map[string]interface{}) (*Session, error) { } func (s *Session) Delete() error { - return s.Bus.Send("", "DELETE", nil) + return s.Send("DELETE", "", nil, nil) } func (s *Session) GetElement(selector Selector) (*Element, error) { var result struct{ Element string } - if err := s.Bus.Send("element", "POST", selector, &result); err != nil { + if err := s.Send("POST", "element", selector, &result); err != nil { return nil, err } @@ -51,7 +40,7 @@ func (s *Session) GetElement(selector Selector) (*Element, error) { func (s *Session) GetElements(selector Selector) ([]*Element, error) { var results []struct{ Element string } - if err := s.Bus.Send("elements", "POST", selector, &results); err != nil { + if err := s.Send("POST", "elements", selector, &results); err != nil { return nil, err } @@ -66,7 +55,7 @@ func (s *Session) GetElements(selector Selector) ([]*Element, error) { func (s *Session) GetActiveElement() (*Element, error) { var result struct{ Element string } - if err := s.Bus.Send("element/active", "POST", nil, &result); err != nil { + if err := s.Send("POST", "element/active", nil, &result); err != nil { return nil, err } @@ -75,7 +64,7 @@ func (s *Session) GetActiveElement() (*Element, error) { func (s *Session) GetWindow() (*Window, error) { var windowID string - if err := s.Bus.Send("window_handle", "GET", nil, &windowID); err != nil { + if err := s.Send("GET", "window_handle", nil, &windowID); err != nil { return nil, err } return &Window{windowID, s}, nil @@ -83,7 +72,7 @@ func (s *Session) GetWindow() (*Window, error) { func (s *Session) GetWindows() ([]*Window, error) { var windowsID []string - if err := s.Bus.Send("window_handles", "GET", nil, &windowsID); err != nil { + if err := s.Send("GET", "window_handles", nil, &windowsID); err != nil { return nil, err } @@ -95,11 +84,15 @@ func (s *Session) GetWindows() ([]*Window, error) { } func (s *Session) SetWindow(window *Window) error { + if window == nil { + return errors.New("nil window is invalid") + } + request := struct { Name string `json:"name"` }{window.ID} - return s.Bus.Send("window", "POST", request) + return s.Send("POST", "window", request, nil) } func (s *Session) SetWindowByName(name string) error { @@ -107,36 +100,47 @@ func (s *Session) SetWindowByName(name string) error { Name string `json:"name"` }{name} - return s.Bus.Send("window", "POST", request) + return s.Send("POST", "window", request, nil) } func (s *Session) DeleteWindow() error { - if err := s.Bus.Send("window", "DELETE", nil, nil); err != nil { + if err := s.Send("DELETE", "window", nil, nil); err != nil { return err } return nil } -func (s *Session) SetCookie(cookie map[string]interface{}) error { +func (s *Session) GetCookies() ([]*Cookie, error) { + var cookies []*Cookie + if err := s.Send("GET", "cookie", nil, &cookies); err != nil { + return nil, err + } + return cookies, nil +} + +func (s *Session) SetCookie(cookie *Cookie) error { + if cookie == nil { + return errors.New("nil cookie is invalid") + } request := struct { - Cookie map[string]interface{} `json:"cookie"` + Cookie *Cookie `json:"cookie"` }{cookie} - return s.Bus.Send("cookie", "POST", request) + return s.Send("POST", "cookie", request, nil) } func (s *Session) DeleteCookie(cookieName string) error { - return s.Bus.Send("cookie/"+cookieName, "DELETE", nil) + return s.Send("DELETE", "cookie/"+cookieName, nil, nil) } func (s *Session) DeleteCookies() error { - return s.Bus.Send("cookie", "DELETE", nil) + return s.Send("DELETE", "cookie", nil, nil) } func (s *Session) GetScreenshot() ([]byte, error) { var base64Image string - if err := s.Bus.Send("screenshot", "GET", nil, &base64Image); err != nil { + if err := s.Send("GET", "screenshot", nil, &base64Image); err != nil { return nil, err } @@ -145,7 +149,7 @@ func (s *Session) GetScreenshot() ([]byte, error) { func (s *Session) GetURL() (string, error) { var url string - if err := s.Bus.Send("url", "GET", nil, &url); err != nil { + if err := s.Send("GET", "url", nil, &url); err != nil { return "", err } @@ -157,12 +161,12 @@ func (s *Session) SetURL(url string) error { URL string `json:"url"` }{url} - return s.Bus.Send("url", "POST", request) + return s.Send("POST", "url", request, nil) } func (s *Session) GetTitle() (string, error) { var title string - if err := s.Bus.Send("title", "GET", nil, &title); err != nil { + if err := s.Send("GET", "title", nil, &title); err != nil { return "", err } @@ -171,22 +175,17 @@ func (s *Session) GetTitle() (string, error) { func (s *Session) GetSource() (string, error) { var source string - if err := s.Bus.Send("source", "GET", nil, &source); err != nil { + if err := s.Send("GET", "source", nil, &source); err != nil { return "", err } return source, nil } -func (s *Session) DoubleClick() error { - return s.Bus.Send("doubleclick", "POST", nil) -} - func (s *Session) MoveTo(region *Element, offset Offset) error { request := map[string]interface{}{} if region != nil { - // TODO: return error if not an element request["element"] = region.ID } @@ -200,7 +199,7 @@ func (s *Session) MoveTo(region *Element, offset Offset) error { } } - return s.Bus.Send("moveto", "POST", request) + return s.Send("POST", "moveto", request, nil) } func (s *Session) Frame(frame *Element) error { @@ -216,11 +215,11 @@ func (s *Session) Frame(frame *Element) error { ID interface{} `json:"id"` }{elementID} - return s.Bus.Send("frame", "POST", request) + return s.Send("POST", "frame", request, nil) } func (s *Session) FrameParent() error { - return s.Bus.Send("frame/parent", "POST", nil) + return s.Send("POST", "frame/parent", nil, nil) } func (s *Session) Execute(body string, arguments []interface{}, result interface{}) error { @@ -233,7 +232,7 @@ func (s *Session) Execute(body string, arguments []interface{}, result interface Args []interface{} `json:"args"` }{body, arguments} - if err := s.Bus.Send("execute", "POST", request, result); err != nil { + if err := s.Send("POST", "execute", request, result); err != nil { return err } @@ -241,20 +240,20 @@ func (s *Session) Execute(body string, arguments []interface{}, result interface } func (s *Session) Forward() error { - return s.Bus.Send("forward", "POST", nil) + return s.Send("POST", "forward", nil, nil) } func (s *Session) Back() error { - return s.Bus.Send("back", "POST", nil) + return s.Send("POST", "back", nil, nil) } func (s *Session) Refresh() error { - return s.Bus.Send("refresh", "POST", nil) + return s.Send("POST", "refresh", nil, nil) } func (s *Session) GetAlertText() (string, error) { var text string - if err := s.Bus.Send("alert_text", "GET", nil, &text); err != nil { + if err := s.Send("GET", "alert_text", nil, &text); err != nil { return "", err } return text, nil @@ -264,15 +263,15 @@ func (s *Session) SetAlertText(text string) error { request := struct { Text string `json:"text"` }{text} - return s.Bus.Send("alert_text", "POST", request) + return s.Send("POST", "alert_text", request, nil) } func (s *Session) AcceptAlert() error { - return s.Bus.Send("accept_alert", "POST", nil) + return s.Send("POST", "accept_alert", nil, nil) } func (s *Session) DismissAlert() error { - return s.Bus.Send("dismiss_alert", "POST", nil) + return s.Send("POST", "dismiss_alert", nil, nil) } func (s *Session) NewLogs(logType string) ([]Log, error) { @@ -281,7 +280,7 @@ func (s *Session) NewLogs(logType string) ([]Log, error) { }{logType} var logs []Log - if err := s.Bus.Send("log", "POST", request, &logs); err != nil { + if err := s.Send("POST", "log", request, &logs); err != nil { return nil, err } return logs, nil @@ -289,16 +288,145 @@ func (s *Session) NewLogs(logType string) ([]Log, error) { func (s *Session) GetLogTypes() ([]string, error) { var types []string - if err := s.Bus.Send("log/types", "GET", nil, &types); err != nil { + if err := s.Send("GET", "log/types", nil, &types); err != nil { return nil, err } return types, nil } -func (s *Session) sendElement(id, endpoint, method string, body interface{}, result ...interface{}) error { - return s.Bus.Send(path.Join("element", id, endpoint), method, body, result...) +func (s *Session) DoubleClick() error { + return s.Send("POST", "doubleclick", nil, nil) +} + +func (s *Session) Click(button Button) error { + request := struct { + Button Button `json:"button"` + }{button} + return s.Send("POST", "click", request, nil) +} + +func (s *Session) ButtonDown(button Button) error { + request := struct { + Button Button `json:"button"` + }{button} + return s.Send("POST", "buttondown", request, nil) +} + +func (s *Session) ButtonUp(button Button) error { + request := struct { + Button Button `json:"button"` + }{button} + return s.Send("POST", "buttonup", request, nil) +} + +func (s *Session) TouchDown(x, y int) error { + request := struct { + X int `json:"x"` + Y int `json:"y"` + }{x, y} + return s.Send("POST", "touch/down", request, nil) +} + +func (s *Session) TouchUp(x, y int) error { + request := struct { + X int `json:"x"` + Y int `json:"y"` + }{x, y} + return s.Send("POST", "touch/up", request, nil) +} + +func (s *Session) TouchMove(x, y int) error { + request := struct { + X int `json:"x"` + Y int `json:"y"` + }{x, y} + return s.Send("POST", "touch/move", request, nil) +} + +func (s *Session) TouchClick(element *Element) error { + if element == nil { + return errors.New("nil element is invalid") + } + + request := struct { + Element string `json:"element"` + }{element.ID} + return s.Send("POST", "touch/click", request, nil) +} + +func (s *Session) TouchDoubleClick(element *Element) error { + if element == nil { + return errors.New("nil element is invalid") + } + + request := struct { + Element string `json:"element"` + }{element.ID} + return s.Send("POST", "touch/doubleclick", request, nil) +} + +func (s *Session) TouchLongClick(element *Element) error { + if element == nil { + return errors.New("nil element is invalid") + } + + request := struct { + Element string `json:"element"` + }{element.ID} + return s.Send("POST", "touch/longclick", request, nil) +} + +func (s *Session) TouchFlick(element *Element, offset Offset, speed Speed) error { + if speed == nil { + return errors.New("nil speed is invalid") + } + + if (element == nil) != (offset == nil) { + return errors.New("element must be provided if offset is provided and vice versa") + } + + var request interface{} + if element == nil { + xSpeed, ySpeed := speed.vector() + request = struct { + XSpeed int `json:"xspeed"` + YSpeed int `json:"yspeed"` + }{xSpeed, ySpeed} + } else { + xOffset, yOffset := offset.position() + request = struct { + Element string `json:"element"` + XOffset int `json:"xoffset"` + YOffset int `json:"yoffset"` + Speed uint `json:"speed"` + }{element.ID, xOffset, yOffset, speed.scalar()} + } + + return s.Send("POST", "touch/flick", request, nil) +} + +func (s *Session) TouchScroll(element *Element, offset Offset) error { + if element == nil { + element = &Element{} + } + + if offset == nil { + return errors.New("nil offset is invalid") + } + + xOffset, yOffset := offset.position() + request := struct { + Element string `json:"element,omitempty"` + XOffset int `json:"xoffset"` + YOffset int `json:"yoffset"` + }{element.ID, xOffset, yOffset} + return s.Send("POST", "touch/scroll", request, nil) +} + +func (s *Session) DeleteLocalStorage() error { + return s.Send("DELETE", "local_storage", nil, nil) } -func (s *Session) sendWindow(id, endpoint, method string, body interface{}, result ...interface{}) error { - return s.Bus.Send(path.Join("window", id, endpoint), method, body, result...) +func (s *Session) DeleteSessionStorage() error { + return s.Send("DELETE", "session_storage", nil, nil) } diff --git a/vendor/github.com/sclevine/agouti/api/session_test.go b/vendor/github.com/sclevine/agouti/api/session_test.go index 911f0cb..0b08163 100644 --- a/vendor/github.com/sclevine/agouti/api/session_test.go +++ b/vendor/github.com/sclevine/agouti/api/session_test.go @@ -7,13 +7,13 @@ import ( . "github.com/onsi/gomega" . "github.com/sclevine/agouti/api" "github.com/sclevine/agouti/api/internal/mocks" + . "github.com/sclevine/agouti/internal/matchers" ) var _ = Describe("Bus", func() { var ( - session *Session bus *mocks.Bus - err error + session *Session ) BeforeEach(func() { @@ -21,33 +21,13 @@ var _ = Describe("Bus", func() { session = &Session{bus} }) - ItShouldMakeARequest := func(method, endpoint string, body ...string) { - It("should make a "+method+" request", func() { - Expect(bus.SendCall.Method).To(Equal(method)) - }) - - It("should hit the desired endpoint", func() { - Expect(bus.SendCall.Endpoint).To(Equal(endpoint)) - }) - - It("should not return an error", func() { - Expect(err).NotTo(HaveOccurred()) - }) - - if len(body) > 0 { - It("should set the request body", func() { - Expect(bus.SendCall.BodyJSON).To(MatchJSON(body[0])) - }) - } - } - Describe("#Delete", func() { - BeforeEach(func() { - err = session.Delete() + It("should successfully send a DELETE to the / endpoint", func() { + Expect(session.Delete()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("")) }) - ItShouldMakeARequest("DELETE", "") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -57,44 +37,48 @@ var _ = Describe("Bus", func() { }) Describe("#GetElement", func() { - var element *Element - - BeforeEach(func() { - bus.SendCall.Result = `{"ELEMENT": "some-id"}` - element, err = session.GetElement(Selector{"css selector", "#selector"}) + It("should successfully send a POST to the element endpoint", func() { + _, err := session.GetElement(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"using": "css selector", "value": "#selector"}`)) }) - ItShouldMakeARequest("POST", "element", `{"using": "css selector", "value": "#selector"}`) - - It("should return an element with an ID and session", func() { + It("should successfully return an element with an ID and session", func() { + bus.SendCall.Result = `{"ELEMENT": "some-id"}` + element, err := session.GetElement(Selector{}) + Expect(err).NotTo(HaveOccurred()) Expect(element.ID).To(Equal("some-id")) - Expect(element.Session).To(Equal(session)) + Expect(element.Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - _, err := session.GetElement(Selector{"css selector", "#selector"}) + _, err := session.GetElement(Selector{}) Expect(err).To(MatchError("some error")) }) }) }) Describe("#GetElements", func() { - var elements []*Element - - BeforeEach(func() { - bus.SendCall.Result = `[{"ELEMENT": "some-id"}, {"ELEMENT": "some-other-id"}]` - elements, err = session.GetElements(Selector{"css selector", "#selector"}) + It("should successfully send a POST to the elements endpoint", func() { + _, err := session.GetElements(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("elements")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"using": "css selector", "value": "#selector"}`)) }) - ItShouldMakeARequest("POST", "elements", `{"using": "css selector", "value": "#selector"}`) - It("should return a slice of elements with IDs and sessions", func() { + bus.SendCall.Result = `[{"ELEMENT": "some-id"}, {"ELEMENT": "some-other-id"}]` + elements, err := session.GetElements(Selector{"css selector", "#selector"}) + Expect(err).NotTo(HaveOccurred()) Expect(elements[0].ID).To(Equal("some-id")) - Expect(elements[0].Session).To(Equal(session)) + Expect(elements[0].Session).To(ExactlyEqual(session)) Expect(elements[1].ID).To(Equal("some-other-id")) - Expect(elements[1].Session).To(Equal(session)) + Expect(elements[1].Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -107,18 +91,19 @@ var _ = Describe("Bus", func() { }) Describe("#GetActiveElement", func() { - var element *Element - - BeforeEach(func() { - bus.SendCall.Result = `{"ELEMENT": "some-id"}` - element, err = session.GetActiveElement() + It("should successfully send a POST to the element/active endpoint", func() { + _, err := session.GetActiveElement() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("element/active")) }) - ItShouldMakeARequest("POST", "element/active") - It("should return the active element with an ID and session", func() { + bus.SendCall.Result = `{"ELEMENT": "some-id"}` + element, err := session.GetActiveElement() + Expect(err).NotTo(HaveOccurred()) Expect(element.ID).To(Equal("some-id")) - Expect(element.Session).To(Equal(session)) + Expect(element.Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -131,18 +116,19 @@ var _ = Describe("Bus", func() { }) Describe("#GetWindow", func() { - var window *Window - - BeforeEach(func() { - bus.SendCall.Result = `"some-id"` - window, err = session.GetWindow() + It("should successfully send a GET to the window_handle endpoint", func() { + _, err := session.GetWindow() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("window_handle")) }) - ItShouldMakeARequest("GET", "window_handle") - It("should return the current window with the retrieved ID and session", func() { + bus.SendCall.Result = `"some-id"` + window, err := session.GetWindow() + Expect(err).NotTo(HaveOccurred()) Expect(window.ID).To(Equal("some-id")) - Expect(window.Session).To(Equal(session)) + Expect(window.Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -155,20 +141,21 @@ var _ = Describe("Bus", func() { }) Describe("#GetWindows", func() { - var windows []*Window - - BeforeEach(func() { - bus.SendCall.Result = `["some-id", "some-other-id"]` - windows, err = session.GetWindows() + It("should successfully send a GET to the window_handles endpoint", func() { + _, err := session.GetWindows() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("window_handles")) }) - ItShouldMakeARequest("GET", "window_handles") - It("should return all windows with their retrieved IDs and sessions", func() { + bus.SendCall.Result = `["some-id", "some-other-id"]` + windows, err := session.GetWindows() + Expect(err).NotTo(HaveOccurred()) Expect(windows[0].ID).To(Equal("some-id")) - Expect(windows[0].Session).To(Equal(session)) + Expect(windows[0].Session).To(ExactlyEqual(session)) Expect(windows[1].ID).To(Equal("some-other-id")) - Expect(windows[1].Session).To(Equal(session)) + Expect(windows[1].Session).To(ExactlyEqual(session)) }) Context("when the bus indicates a failure", func() { @@ -181,45 +168,51 @@ var _ = Describe("Bus", func() { }) Describe("#SetWindow", func() { - var window *Window - - BeforeEach(func() { - window = &Window{ID: "some-id"} - err = session.SetWindow(window) + It("should successfully send a POST to the window endpoint", func() { + window := &Window{ID: "some-id"} + Expect(session.SetWindow(window)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("window")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"name": "some-id"}`)) }) - ItShouldMakeARequest("POST", "window", `{"name": "some-id"}`) + Context("when the window is nil", func() { + It("should return an error", func() { + Expect(session.SetWindow(nil)).To(MatchError("nil window is invalid")) + }) + }) Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.SetWindow(window)).To(MatchError("some error")) + Expect(session.SetWindow(&Window{})).To(MatchError("some error")) }) }) }) Describe("#SetWindowByName", func() { - BeforeEach(func() { - err = session.SetWindowByName("some name") + It("should successfully send a POST to the window endpoint", func() { + Expect(session.SetWindowByName("some name")).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("window")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"name": "some name"}`)) }) - ItShouldMakeARequest("POST", "window", `{"name": "some name"}`) - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.SetWindowByName("some name")).To(MatchError("some error")) + Expect(session.SetWindowByName("")).To(MatchError("some error")) }) }) }) Describe("#DeleteWindow", func() { - BeforeEach(func() { - err = session.DeleteWindow() + It("should successfully send a DELETE to the window endpoint", func() { + Expect(session.DeleteWindow()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("window")) }) - ItShouldMakeARequest("DELETE", "window") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -229,46 +222,77 @@ var _ = Describe("Bus", func() { }) }) - Describe("#SetCookie", func() { - var cookie map[string]interface{} + Describe("#GetCookies", func() { + It("should successfully send a GET to the cookie endpoint", func() { + _, err := session.GetCookies() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("cookie")) + }) + + It("should return the cookies", func() { + bus.SendCall.Result = `[{"name": "some-cookie"}, {"name": "some-other-cookie"}]` + cookies, err := session.GetCookies() + Expect(err).NotTo(HaveOccurred()) + Expect(cookies).To(Equal([]*Cookie{ + {Name: "some-cookie"}, + {Name: "some-other-cookie"}, + })) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + _, err := session.GetCookies() + Expect(err).To(MatchError("some error")) + }) + }) + }) - BeforeEach(func() { - cookie = map[string]interface{}{"name": "some-cookie"} - err = session.SetCookie(cookie) + Describe("#SetCookie", func() { + It("should successfully send a POST to the cookie endpoint", func() { + Expect(session.SetCookie(&Cookie{Name: "some-cookie"})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("cookie")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"cookie": {"name": "some-cookie", "value": ""}}`)) }) - ItShouldMakeARequest("POST", "cookie", `{"cookie": {"name": "some-cookie"}}`) + Context("when the cookie is nil", func() { + It("should return an error", func() { + Expect(session.SetCookie(nil)).To(MatchError("nil cookie is invalid")) + }) + }) Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.SetCookie(cookie)).To(MatchError("some error")) + Expect(session.SetCookie(&Cookie{})).To(MatchError("some error")) }) }) }) Describe("#DeleteCookie", func() { - BeforeEach(func() { - err = session.DeleteCookie("some-cookie") + It("should successfully send a DELETE to the cookie/some-cookie endpoint", func() { + Expect(session.DeleteCookie("some-cookie")).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("cookie/some-cookie")) }) - ItShouldMakeARequest("DELETE", "cookie/some-cookie") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.DeleteCookie("some-cookie")).To(MatchError("some error")) + Expect(session.DeleteCookie("")).To(MatchError("some error")) }) }) }) Describe("#DeleteCookies", func() { - BeforeEach(func() { - err = session.DeleteCookies() + It("should successfully send a DELETE to the cookie endpoint", func() { + Expect(session.DeleteCookies()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("cookie")) }) - ItShouldMakeARequest("DELETE", "cookie") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -278,17 +302,18 @@ var _ = Describe("Bus", func() { }) Describe("#GetScreenshot", func() { - var image []byte - - BeforeEach(func() { - bus.SendCall.Result = `"c29tZS1wbmc="` - image, err = session.GetScreenshot() + It("should successfully send a GET to the screenshot endpoint", func() { + _, err := session.GetScreenshot() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("screenshot")) }) - ItShouldMakeARequest("GET", "screenshot") - Context("when the image is valid base64", func() { It("should return the decoded image", func() { + bus.SendCall.Result = `"c29tZS1wbmc="` + image, err := session.GetScreenshot() + Expect(err).NotTo(HaveOccurred()) Expect(string(image)).To(Equal("some-png")) }) }) @@ -311,16 +336,17 @@ var _ = Describe("Bus", func() { }) Describe("#GetURL", func() { - var url string - - BeforeEach(func() { - bus.SendCall.Result = `"http://example.com"` - url, err = session.GetURL() + It("should successfully send a GET to the url endpoint", func() { + _, err := session.GetURL() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("url")) }) - ItShouldMakeARequest("GET", "url") - It("should return the page URL", func() { + bus.SendCall.Result = `"http://example.com"` + url, err := session.GetURL() + Expect(err).NotTo(HaveOccurred()) Expect(url).To(Equal("http://example.com")) }) @@ -334,54 +360,57 @@ var _ = Describe("Bus", func() { }) Describe("#SetURL", func() { - BeforeEach(func() { - err = session.SetURL("http://example.com") + It("should successfully send a POST to the url endpoint", func() { + Expect(session.SetURL("http://example.com")).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("url")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"url": "http://example.com"}`)) }) - ItShouldMakeARequest("POST", "url", `{"url": "http://example.com"}`) - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.SetURL("http://example.com")).To(MatchError("some error")) + Expect(session.SetURL("")).To(MatchError("some error")) }) }) }) Describe("#GetTitle", func() { - var title string - - BeforeEach(func() { - bus.SendCall.Result = `"Some Title"` - title, err = session.GetTitle() + It("should successfully send a GET to the title endpoint", func() { + _, err := session.GetTitle() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("title")) }) - ItShouldMakeARequest("GET", "title") - It("should return the page title", func() { + bus.SendCall.Result = `"Some Title"` + title, err := session.GetTitle() + Expect(err).NotTo(HaveOccurred()) Expect(title).To(Equal("Some Title")) }) Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - _, err = session.GetTitle() + _, err := session.GetTitle() Expect(err).To(MatchError("some error")) }) }) }) Describe("#GetSource", func() { - var source string - - BeforeEach(func() { - bus.SendCall.Result = `"some source"` - source, err = session.GetSource() + It("should successfully send a GET to the source endpoint", func() { + _, err := session.GetSource() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("source")) }) - ItShouldMakeARequest("GET", "source") - It("should return the page source", func() { + bus.SendCall.Result = `"some source"` + source, err := session.GetSource() + Expect(err).NotTo(HaveOccurred()) Expect(source).To(Equal("some source")) }) @@ -394,32 +423,19 @@ var _ = Describe("Bus", func() { }) }) - Describe("#DoubleClick", func() { - BeforeEach(func() { - err = session.DoubleClick() - }) - - ItShouldMakeARequest("POST", "doubleclick") - - Context("when the bus indicates a failure", func() { - It("should return an error", func() { - bus.SendCall.Err = errors.New("some error") - Expect(session.DoubleClick()).To(MatchError("some error")) - }) - }) - }) - Describe("#MoveTo", func() { - BeforeEach(func() { - err = session.MoveTo(nil, nil) + It("should successfully send a POST to the moveto endpoint", func() { + Expect(session.MoveTo(nil, nil)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("moveto")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON("{}")) }) - ItShouldMakeARequest("POST", "moveto", "{}") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.MoveTo(nil, nil)).To(MatchError("some error")) + err := session.MoveTo(nil, nil) + Expect(err).To(MatchError("some error")) }) }) @@ -454,35 +470,37 @@ var _ = Describe("Bus", func() { }) Describe("#Frame", func() { - BeforeEach(func() { - err = session.Frame(&Element{ID: "some-id"}) + It("should successfully send a POST to the frame endpoint", func() { + Expect(session.Frame(&Element{ID: "some-id"})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("frame")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"id": {"ELEMENT": "some-id"}}`)) }) - ItShouldMakeARequest("POST", "frame", `{"id": {"ELEMENT": "some-id"}}`) - Context("When the provided frame in nil", func() { - BeforeEach(func() { - err = session.Frame(nil) + It("should successfully send a POST to the frame endpoint", func() { + Expect(session.Frame(nil)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("frame")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"id": null}`)) }) - - ItShouldMakeARequest("POST", "frame", `{"id": null}`) }) Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.Frame(&Element{ID: "some-id"})).To(MatchError("some error")) + Expect(session.Frame(nil)).To(MatchError("some error")) }) }) }) Describe("#FrameParent", func() { - BeforeEach(func() { - err = session.FrameParent() + It("should successfully send a POST to the frame/parent endpoint", func() { + Expect(session.FrameParent()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("frame/parent")) }) - ItShouldMakeARequest("POST", "frame/parent") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -492,19 +510,18 @@ var _ = Describe("Bus", func() { }) Describe("#Execute", func() { - var ( - result struct{ Some string } - err error - ) - - BeforeEach(func() { - bus.SendCall.Result = `{"some": "result"}` - err = session.Execute("some javascript code", []interface{}{1, "two"}, &result) + It("should successfully send a POST to the execute endpoint", func() { + Expect(session.Execute("some javascript code", []interface{}{1, "two"}, nil)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("execute")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"script": "some javascript code", "args": [1, "two"]}`)) }) - ItShouldMakeARequest("POST", "execute", `{"script": "some javascript code", "args": [1, "two"]}`) - It("should fill the provided results interface", func() { + var result struct{ Some string } + bus.SendCall.Result = `{"some": "result"}` + err := session.Execute("some javascript code", []interface{}{1, "two"}, &result) + Expect(err).NotTo(HaveOccurred()) Expect(result.Some).To(Equal("result")) }) @@ -518,18 +535,18 @@ var _ = Describe("Bus", func() { Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") - Expect(session.Execute("", nil, &result)).To(MatchError("some error")) + Expect(session.Execute("", nil, nil)).To(MatchError("some error")) }) }) }) Describe("#Forward", func() { - BeforeEach(func() { - err = session.Forward() + It("should successfully send a POST to the forward endpoint", func() { + Expect(session.Forward()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("forward")) }) - ItShouldMakeARequest("POST", "forward") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -539,12 +556,12 @@ var _ = Describe("Bus", func() { }) Describe("#Back", func() { - BeforeEach(func() { - err = session.Back() + It("should successfully send a POST to the back endpoint", func() { + Expect(session.Back()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("back")) }) - ItShouldMakeARequest("POST", "back") - Context("when the bus indicates a failure", func() { It("should return an error indicating the bus failed to go back in history", func() { bus.SendCall.Err = errors.New("some error") @@ -554,12 +571,12 @@ var _ = Describe("Bus", func() { }) Describe("#Refresh", func() { - BeforeEach(func() { - err = session.Refresh() + It("should successfully send a POST to the refresh endpoint", func() { + Expect(session.Refresh()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("refresh")) }) - ItShouldMakeARequest("POST", "refresh") - Context("when the bus indicates a failure", func() { It("should return an error indicating the bus failed to refresh the page", func() { bus.SendCall.Err = errors.New("some error") @@ -569,16 +586,17 @@ var _ = Describe("Bus", func() { }) Describe("#GetAlertText", func() { - var text string - - BeforeEach(func() { - bus.SendCall.Result = `"some text"` - text, err = session.GetAlertText() + It("should successfully send a GET to the alert_text endpoint", func() { + _, err := session.GetAlertText() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("alert_text")) }) - ItShouldMakeARequest("GET", "alert_text") - It("should return the current alert text", func() { + bus.SendCall.Result = `"some text"` + text, err := session.GetAlertText() + Expect(err).NotTo(HaveOccurred()) Expect(text).To(Equal("some text")) }) @@ -592,12 +610,13 @@ var _ = Describe("Bus", func() { }) Describe("#SetAlertText", func() { - BeforeEach(func() { - err = session.SetAlertText("some text") + It("should successfully send a POST to the alert_text endpoint", func() { + Expect(session.SetAlertText("some text")).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("alert_text")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"text": "some text"}`)) }) - ItShouldMakeARequest("POST", "alert_text", `{"text": "some text"}`) - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -607,12 +626,12 @@ var _ = Describe("Bus", func() { }) Describe("#AcceptAlert", func() { - BeforeEach(func() { - err = session.AcceptAlert() + It("should successfully send a POST to the accept_alert endpoint", func() { + Expect(session.AcceptAlert()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("accept_alert")) }) - ItShouldMakeARequest("POST", "accept_alert") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -622,12 +641,12 @@ var _ = Describe("Bus", func() { }) Describe("#DismissAlert", func() { - BeforeEach(func() { - err = session.DismissAlert() + It("should successfully send a POST to the dismiss_alert endpoint", func() { + Expect(session.DismissAlert()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("dismiss_alert")) }) - ItShouldMakeARequest("POST", "dismiss_alert") - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") @@ -637,19 +656,21 @@ var _ = Describe("Bus", func() { }) Describe("#NewLogs", func() { - var logs []Log + It("should successfully send a POST to the log endpoint", func() { + _, err := session.NewLogs("browser") + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("log")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"type": "browser"}`)) + }) - BeforeEach(func() { + It("should return all logs", func() { bus.SendCall.Result = `[ {"message": "some message", "level": "INFO", "timestamp": 1417988844498}, {"message": "some other message", "level": "WARNING", "timestamp": 1417982864598} ]` - logs, err = session.NewLogs("browser") - }) - - ItShouldMakeARequest("POST", "log", `{"type": "browser"}`) - - It("should return all logs", func() { + logs, err := session.NewLogs("browser") + Expect(err).NotTo(HaveOccurred()) Expect(logs[0].Message).To(Equal("some message")) Expect(logs[0].Level).To(Equal("INFO")) Expect(logs[0].Timestamp).To(BeEquivalentTo(1417988844498)) @@ -668,16 +689,17 @@ var _ = Describe("Bus", func() { }) Describe("#GetLogTypes", func() { - var types []string - - BeforeEach(func() { - bus.SendCall.Result = `["first type", "second type"]` - types, err = session.GetLogTypes() + It("should successfully send a GET to the log/types endpoint", func() { + _, err := session.GetLogTypes() + Expect(err).NotTo(HaveOccurred()) + Expect(bus.SendCall.Method).To(Equal("GET")) + Expect(bus.SendCall.Endpoint).To(Equal("log/types")) }) - ItShouldMakeARequest("GET", "log/types") - It("should return the current alert text", func() { + bus.SendCall.Result = `["first type", "second type"]` + types, err := session.GetLogTypes() + Expect(err).NotTo(HaveOccurred()) Expect(types).To(Equal([]string{"first type", "second type"})) }) @@ -689,4 +711,342 @@ var _ = Describe("Bus", func() { }) }) }) + + Describe("#DoubleClick", func() { + It("should successfully send a POST to the doubleclick endpoint", func() { + Expect(session.DoubleClick()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("doubleclick")) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.DoubleClick()).To(MatchError("some error")) + }) + }) + }) + + Describe("#Click", func() { + It("should successfully send a POST to the click endpoint", func() { + Expect(session.Click(RightButton)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("click")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"button": 2}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.Click(RightButton)).To(MatchError("some error")) + }) + }) + }) + + Describe("#ButtonDown", func() { + It("should successfully send a POST to the buttondown endpoint", func() { + Expect(session.ButtonDown(RightButton)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("buttondown")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"button": 2}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.ButtonDown(RightButton)).To(MatchError("some error")) + }) + }) + }) + + Describe("#ButtonUp", func() { + It("should successfully send a POST to the buttonup endpoint", func() { + Expect(session.ButtonUp(RightButton)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("buttonup")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"button": 2}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.ButtonUp(RightButton)).To(MatchError("some error")) + }) + }) + }) + + Describe("#TouchDown", func() { + It("should successfully send a POST to the touch/down endpoint", func() { + Expect(session.TouchDown(100, 200)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/down")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"x": 100, "y": 200}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchDown(100, 200)).To(MatchError("some error")) + }) + }) + }) + + Describe("#TouchUp", func() { + It("should successfully send a POST to the touch/up endpoint", func() { + Expect(session.TouchUp(100, 200)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/up")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"x": 100, "y": 200}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchUp(100, 200)).To(MatchError("some error")) + }) + }) + }) + + Describe("#TouchMove", func() { + It("should successfully send a POST to the touch/move endpoint", func() { + Expect(session.TouchMove(100, 200)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/move")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"x": 100, "y": 200}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchMove(100, 200)).To(MatchError("some error")) + }) + }) + }) + + Describe("#TouchClick", func() { + It("should successfully send a POST to the touch/click endpoint", func() { + Expect(session.TouchClick(&Element{ID: "some-element-id"})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/click")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"element": "some-element-id"}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchClick(&Element{ID: "some-element-id"})).To(MatchError("some error")) + }) + }) + + Context("when the element is nil", func() { + It("shoul return an error", func() { + Expect(session.TouchClick(nil)).To(MatchError("nil element is invalid")) + }) + }) + }) + + Describe("#TouchDoubleClick", func() { + It("should successfully send a POST to the touch/doubleclick endpoint", func() { + Expect(session.TouchDoubleClick(&Element{ID: "some-element-id"})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/doubleclick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"element": "some-element-id"}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchDoubleClick(&Element{ID: "some-element-id"})).To(MatchError("some error")) + }) + }) + + Context("when the element is nil", func() { + It("shoul return an error", func() { + Expect(session.TouchDoubleClick(nil)).To(MatchError("nil element is invalid")) + }) + }) + }) + + Describe("#TouchLongClick", func() { + It("should successfully send a POST to the touch/longclick endpoint", func() { + Expect(session.TouchLongClick(&Element{ID: "some-element-id"})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/longclick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"element": "some-element-id"}`)) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchLongClick(&Element{ID: "some-element-id"})).To(MatchError("some error")) + }) + }) + + Context("when the element is nil", func() { + It("shoul return an error", func() { + Expect(session.TouchLongClick(nil)).To(MatchError("nil element is invalid")) + }) + }) + }) + + Describe("#TouchFlick", func() { + Context("when provided with an offset and element", func() { + var ( + element *Element + offset Offset + ) + + BeforeEach(func() { + element = &Element{ID: "some-element-id"} + offset = XYOffset{X: 100, Y: 200} + }) + + Context("when provided with a scalar speed", func() { + It("should successfully send a POST to the touch/flick endpoint", func() { + Expect(session.TouchFlick(element, offset, ScalarSpeed(300))).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/flick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "element": "some-element-id", + "xoffset": 100, + "yoffset": 200, + "speed": 300 + }`)) + }) + }) + + Context("when provided with a vector speed", func() { + It("should successfully send a POST to the touch/flick endpoint", func() { + Expect(session.TouchFlick(element, offset, VectorSpeed{X: 300, Y: 400})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/flick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "element": "some-element-id", + "xoffset": 100, + "yoffset": 200, + "speed": 500 + }`)) + }) + }) + }) + + Context("when provided with no offset or element", func() { + Context("when provided with a scalar speed", func() { + It("should successfully send a POST to the touch/flick endpoint", func() { + Expect(session.TouchFlick(nil, nil, ScalarSpeed(5))).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/flick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "xspeed": 3, + "yspeed": 3 + }`)) + }) + }) + + Context("when provided with a vector speed", func() { + It("should successfully send a POST to the touch/flick endpoint", func() { + Expect(session.TouchFlick(nil, nil, VectorSpeed{X: 100, Y: 200})).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/flick")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "xspeed": 100, + "yspeed": 200 + }`)) + }) + }) + }) + + Context("when provided with an element but no offset", func() { + It("should return an error", func() { + Expect(session.TouchFlick(&Element{}, nil, ScalarSpeed(0))).To(MatchError("element must be provided if offset is provided and vice versa")) + }) + }) + + Context("when provided with an offset but no element", func() { + It("should return an error", func() { + Expect(session.TouchFlick(nil, XYOffset{}, ScalarSpeed(0))).To(MatchError("element must be provided if offset is provided and vice versa")) + }) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.TouchFlick(nil, nil, ScalarSpeed(0))).To(MatchError("some error")) + }) + }) + }) + + Describe("#TouchScroll", func() { + Context("when provided with an offset and element", func() { + It("should successfully send a POST to the touch/scroll endpoint", func() { + element := &Element{ID: "some-element-id"} + offset := XYOffset{X: 100, Y: 200} + Expect(session.TouchScroll(element, offset)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/scroll")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "element": "some-element-id", + "xoffset": 100, + "yoffset": 200 + }`)) + }) + }) + + Context("when provided with only an offset", func() { + It("should successfully send a POST to the touch/scroll endpoint", func() { + offset := XYOffset{X: 100, Y: 200} + Expect(session.TouchScroll(nil, offset)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("touch/scroll")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{ + "xoffset": 100, + "yoffset": 200 + }`)) + }) + }) + + Context("when provided with no offset", func() { + It("should return an error", func() { + Expect(session.TouchScroll(&Element{}, nil)).To(MatchError("nil offset is invalid")) + }) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + offset := XYOffset{X: 100, Y: 200} + Expect(session.TouchScroll(nil, offset)).To(MatchError("some error")) + }) + }) + }) + + Describe("#DeleteLocalStorage", func() { + It("should successfully send a POST to the delete local storage endpoint", func() { + Expect(session.DeleteLocalStorage()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("local_storage")) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.DeleteLocalStorage()).To(MatchError("some error")) + }) + }) + }) + + Describe("#DeleteSessionStorage", func() { + It("should successfully send a POST to the delete session storage endpoint", func() { + Expect(session.DeleteSessionStorage()).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("DELETE")) + Expect(bus.SendCall.Endpoint).To(Equal("session_storage")) + }) + + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + Expect(session.DeleteSessionStorage()).To(MatchError("some error")) + }) + }) + }) }) diff --git a/vendor/github.com/sclevine/agouti/api/speed.go b/vendor/github.com/sclevine/agouti/api/speed.go new file mode 100644 index 0000000..c4da068 --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/speed.go @@ -0,0 +1,32 @@ +package api + +import "math" + +type Speed interface { + vector() (x, y int) + scalar() uint +} + +type VectorSpeed struct { + X int + Y int +} + +func (s VectorSpeed) vector() (x, y int) { + return s.X, s.Y +} + +func (s VectorSpeed) scalar() uint { + return uint(math.Hypot(float64(s.X), float64(s.Y))) +} + +type ScalarSpeed uint + +func (s ScalarSpeed) vector() (x, y int) { + scalar := int(float64(s) / math.Sqrt2) + return scalar, scalar +} + +func (s ScalarSpeed) scalar() uint { + return uint(s) +} diff --git a/vendor/github.com/sclevine/agouti/api/types.go b/vendor/github.com/sclevine/agouti/api/types.go new file mode 100644 index 0000000..5dad785 --- /dev/null +++ b/vendor/github.com/sclevine/agouti/api/types.go @@ -0,0 +1,44 @@ +package api + +type Log struct { + Message string + Level string + Timestamp int64 +} + +// A Cookie defines a web cookie +type Cookie struct { + // Name is the name of the cookie (required) + Name string `json:"name"` + + // Value is the value of the cookie (required) + Value string `json:"value"` + + // Path is the path of the cookie (default: "/") + Path string `json:"path,omitempty"` + + // Domain is the domain of the cookie (default: current page domain) + Domain string `json:"domain,omitempty"` + + // Secure is set to true for secure cookies (default: false) + Secure bool `json:"secure,omitempty"` + + // HTTPOnly is set to true for HTTP-Only cookies (default: false) + HTTPOnly bool `json:"httpOnly,omitempty"` + + // Expiry is the time when the cookie expires + Expiry int64 `json:"expiry,omitempty"` +} + +type Selector struct { + Using string `json:"using"` + Value string `json:"value"` +} + +type Button int + +const ( + LeftButton Button = iota + MiddleButton + RightButton +) diff --git a/vendor/github.com/sclevine/agouti/api/webdriver.go b/vendor/github.com/sclevine/agouti/api/webdriver.go index cc49c4f..ca8f005 100644 --- a/vendor/github.com/sclevine/agouti/api/webdriver.go +++ b/vendor/github.com/sclevine/agouti/api/webdriver.go @@ -4,20 +4,21 @@ import ( "fmt" "time" - "github.com/sclevine/agouti/api/internal/bus" "github.com/sclevine/agouti/api/internal/service" ) type WebDriver struct { Timeout time.Duration - Service driverService + Debug bool + service driverService sessions []*Session } type driverService interface { - URL() (string, error) - Start(timeout time.Duration) error + URL() string + Start(debug bool) error Stop() error + WaitForBoot(timeout time.Duration) error } func NewWebDriver(url string, command []string) *WebDriver { @@ -27,32 +28,40 @@ func NewWebDriver(url string, command []string) *WebDriver { } return &WebDriver{ - Timeout: 5 * time.Second, - Service: driverService, + Timeout: 10 * time.Second, + service: driverService, } } +func (w *WebDriver) URL() string { + return w.service.URL() +} + func (w *WebDriver) Open(desiredCapabilites map[string]interface{}) (*Session, error) { - url, err := w.Service.URL() - if err != nil { - return nil, fmt.Errorf("cannot retrieve URL: %s", err) + url := w.service.URL() + if url == "" { + return nil, fmt.Errorf("service not started") } - busClient, err := bus.Connect(url, desiredCapabilites) + session, err := Open(url, desiredCapabilites) if err != nil { - return nil, fmt.Errorf("failed to connect: %s", err) + return nil, err } - session := &Session{busClient} w.sessions = append(w.sessions, session) return session, nil } func (w *WebDriver) Start() error { - if err := w.Service.Start(w.Timeout); err != nil { + if err := w.service.Start(w.Debug); err != nil { return fmt.Errorf("failed to start service: %s", err) } + if err := w.service.WaitForBoot(w.Timeout); err != nil { + w.service.Stop() + return err + } + return nil } @@ -61,7 +70,7 @@ func (w *WebDriver) Stop() error { session.Delete() } - if err := w.Service.Stop(); err != nil { + if err := w.service.Stop(); err != nil { return fmt.Errorf("failed to stop service: %s", err) } diff --git a/vendor/github.com/sclevine/agouti/api/webdriver_test.go b/vendor/github.com/sclevine/agouti/api/webdriver_test.go index ec39eee..be5bdae 100644 --- a/vendor/github.com/sclevine/agouti/api/webdriver_test.go +++ b/vendor/github.com/sclevine/agouti/api/webdriver_test.go @@ -21,7 +21,8 @@ var _ = Describe("WebDriver", func() { BeforeEach(func() { service = &mocks.Service{} - webDriver = &WebDriver{Timeout: 2 * time.Second, Service: service} + webDriver = NewTestWebDriver(service) + webDriver.Timeout = 2 * time.Second }) Describe("#Open", func() { @@ -33,6 +34,7 @@ var _ = Describe("WebDriver", func() { ) BeforeEach(func() { + responseBody = `{"sessionId": "some-id"}` server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { requestBodyBytes, _ := ioutil.ReadAll(request.Body) requestBody = string(requestBodyBytes) @@ -46,42 +48,38 @@ var _ = Describe("WebDriver", func() { server.Close() }) - It("should successfully return a session with a bus that talks to the WebDriver", func() { - responseBody = `{"sessionId": "some-id"}` - session, err := webDriver.Open(nil) + It("should successfully return a session with the desired capabilities", func() { + session, err := webDriver.Open(map[string]interface{}{"some": "capability"}) Expect(err).NotTo(HaveOccurred()) + Expect(requestBody).To(Equal(`{"desiredCapabilities":{"some":"capability"}}`)) responseBody = `{"value": "some title"}` Expect(session.GetTitle()).To(Equal("some title")) }) - It("should open the connection with the provided desired capabilities", func() { - webDriver.Open(map[string]interface{}{"some": "capability"}) - Expect(requestBody).To(Equal(`{"desiredCapabilities":{"some":"capability"}}`)) + Context("when the WebDriver is stopped", func() { + It("should delete the opened session stored by the WebDriver", func() { + _, err := webDriver.Open(nil) + Expect(err).NotTo(HaveOccurred()) + requestMethod = "" + Expect(webDriver.Stop()).To(Succeed()) + Expect(requestBody).To(Equal("")) + Expect(requestMethod).To(Equal("DELETE")) + }) }) - Context("when the service URL cannot be retrieved", func() { + Context("when the WebDriver is not running", func() { It("should return an error", func() { - service.URLCall.Err = errors.New("some error") + service.URLCall.ReturnURL = "" _, err := webDriver.Open(nil) - Expect(err).To(MatchError("cannot retrieve URL: some error")) + Expect(err).To(MatchError("service not started")) }) }) Context("when we cannot connect to the WebDriver bus", func() { It("should return an error", func() { + responseBody = `{"sessionId": ""}` _, err := webDriver.Open(nil) - Expect(err).To(MatchError("failed to connect: failed to retrieve a session ID")) - }) - }) - - Context("when the WebDriver is stopped", func() { - It("should delete the opened session", func() { - responseBody = `{"sessionId": "some-id"}` - webDriver.Open(nil) - requestMethod = "" - webDriver.Stop() - Expect(requestBody).To(Equal("")) - Expect(requestMethod).To(Equal("DELETE")) + Expect(err).To(MatchError("failed to retrieve a session ID")) }) }) }) @@ -89,7 +87,15 @@ var _ = Describe("WebDriver", func() { Describe("#Start", func() { It("should successfully start the WebDriver service", func() { Expect(webDriver.Start()).To(Succeed()) - Expect(service.StartCall.Timeout).To(Equal(2 * time.Second)) + Expect(service.StartCall.Called).To(BeTrue()) + Expect(service.StartCall.Debug).To(BeFalse()) + Expect(service.WaitForBootCall.Timeout).To(Equal(2 * time.Second)) + }) + + It("should start the service in debug mode when specified", func() { + webDriver.Debug = true + Expect(webDriver.Start()).To(Succeed()) + Expect(service.StartCall.Debug).To(BeTrue()) }) Context("when the WebDriver service cannot be started", func() { @@ -99,6 +105,15 @@ var _ = Describe("WebDriver", func() { Expect(err).To(MatchError("failed to start service: some error")) }) }) + + Context("when the WebDriver fails to start within the allotted timeout", func() { + It("should return an error and stop the service", func() { + service.WaitForBootCall.Err = errors.New("some error") + err := webDriver.Start() + Expect(err).To(MatchError("some error")) + Expect(service.StopCall.Called).To(BeTrue()) + }) + }) }) Describe("#Stop", func() { diff --git a/vendor/github.com/sclevine/agouti/api/window.go b/vendor/github.com/sclevine/agouti/api/window.go index 055f643..52509d5 100644 --- a/vendor/github.com/sclevine/agouti/api/window.go +++ b/vendor/github.com/sclevine/agouti/api/window.go @@ -1,15 +1,21 @@ package api +import "path" + type Window struct { ID string Session *Session } +func (w *Window) Send(method, endpoint string, body, result interface{}) error { + return w.Session.Send(method, path.Join("window", w.ID, endpoint), body, result) +} + func (w *Window) SetSize(width, height int) error { request := struct { Width int `json:"width"` Height int `json:"height"` }{width, height} - return w.Session.sendWindow(w.ID, "size", "POST", request) + return w.Send("POST", "size", request, nil) } diff --git a/vendor/github.com/sclevine/agouti/api/window_test.go b/vendor/github.com/sclevine/agouti/api/window_test.go index 872b68c..4768045 100644 --- a/vendor/github.com/sclevine/agouti/api/window_test.go +++ b/vendor/github.com/sclevine/agouti/api/window_test.go @@ -13,7 +13,6 @@ var _ = Describe("Window", func() { var ( window *Window bus *mocks.Bus - err error ) BeforeEach(func() { @@ -21,33 +20,38 @@ var _ = Describe("Window", func() { window = &Window{"some-id", &Session{bus}} }) - ItShouldMakeAWindowRequest := func(method, endpoint string, body ...string) { - It("should make a "+method+" request", func() { - Expect(bus.SendCall.Method).To(Equal(method)) + Describe("#Send", func() { + It("should successfully send a request to the provided endpoint", func() { + Expect(window.Send("method", "endpoint", "body", nil)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("method")) + Expect(bus.SendCall.Endpoint).To(Equal("window/some-id/endpoint")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`"body"`)) }) - It("should hit the desired endpoint", func() { - Expect(bus.SendCall.Endpoint).To(Equal("window/some-id/" + endpoint)) + It("should retrieve the result", func() { + var result string + bus.SendCall.Result = `"some result"` + Expect(window.Send("method", "endpoint", "body", &result)).To(Succeed()) + Expect(result).To(Equal("some result")) }) - It("should not return an error", func() { - Expect(err).NotTo(HaveOccurred()) - }) - - if len(body) > 0 { - It("should set the request body", func() { - Expect(bus.SendCall.BodyJSON).To(MatchJSON(body[0])) + Context("when the bus indicates a failure", func() { + It("should return an error", func() { + bus.SendCall.Err = errors.New("some error") + err := window.Send("method", "endpoint", "body", nil) + Expect(err).To(MatchError("some error")) }) - } - } + }) + }) Describe("#SetSize", func() { - BeforeEach(func() { - err = window.SetSize(640, 480) + It("should successfully send a POST request to the size endpoint", func() { + Expect(window.SetSize(640, 480)).To(Succeed()) + Expect(bus.SendCall.Method).To(Equal("POST")) + Expect(bus.SendCall.Endpoint).To(Equal("window/some-id/size")) + Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"width":640,"height":480}`)) }) - ItShouldMakeAWindowRequest("POST", "size", `{"width":640,"height":480}`) - Context("when the bus indicates a failure", func() { It("should return an error", func() { bus.SendCall.Err = errors.New("some error") diff --git a/vendor/github.com/sclevine/agouti/cookie.go b/vendor/github.com/sclevine/agouti/cookie.go deleted file mode 100644 index 3e9d9ff..0000000 --- a/vendor/github.com/sclevine/agouti/cookie.go +++ /dev/null @@ -1,48 +0,0 @@ -package agouti - -import "encoding/json" - -// Cookie defines a cookie for use with *Page#SetCookie() -type Cookie map[string]interface{} - -// NewCookie returns a Cookie instance with the provided name and value. -// All methods called on this instance will modify the original instance. -func NewCookie(name string, value string) Cookie { - return Cookie{"name": name, "value": value} -} - -// Path sets the cookie path - defaults to "/". -func (c Cookie) Path(path string) Cookie { - c["path"] = path - return c -} - -// Domain sets the domain that the cookie is visible to. -func (c Cookie) Domain(domain string) Cookie { - c["domain"] = domain - return c -} - -// SetSecure marks the cookie as a secure cookie -func (c Cookie) SetSecure() Cookie { - c["secure"] = true - return c -} - -// SetHTTPOnly marks the cookie as HTTP-only -func (c Cookie) SetHTTPOnly() Cookie { - c["httpOnly"] = true - return c -} - -// Expiry sets when the cookie expires in Unix time. -func (c Cookie) Expiry(expiry int64) Cookie { - c["expiry"] = expiry - return c -} - -// JSON returns a JSON string representing the cookie. -func (c Cookie) JSON() (string, error) { - cookieJSON, err := json.Marshal(c) - return string(cookieJSON), err -} diff --git a/vendor/github.com/sclevine/agouti/cookie_test.go b/vendor/github.com/sclevine/agouti/cookie_test.go deleted file mode 100644 index cc4c5cd..0000000 --- a/vendor/github.com/sclevine/agouti/cookie_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package agouti_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - . "github.com/sclevine/agouti" -) - -var _ = Describe("Cookie", func() { - var cookie Cookie - - BeforeEach(func() { - cookie = NewCookie("some-name", "some value") - }) - - It("should successfully encode all provided options into JSON", func() { - cookie.Path("some/path").Domain("some.domain") - cookie.SetSecure().SetHTTPOnly().Expiry(1000) - Expect(cookie.JSON()).To(MatchJSON(`{ - "name": "some-name", - "value": "some value", - "path": "some/path", - "domain": "some.domain", - "secure": true, - "httpOnly": true, - "expiry": 1000 - }`)) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/capabilities.go b/vendor/github.com/sclevine/agouti/core/capabilities.go deleted file mode 100644 index b74bd33..0000000 --- a/vendor/github.com/sclevine/agouti/core/capabilities.go +++ /dev/null @@ -1,75 +0,0 @@ -package core - -import "encoding/json" - -// A Capabilities instance defines the desired capabilities the WebDriver -// should use to configure a Page. -// -// For example, to open a Firefox page with JavaScript disabled: -// driver.Page(Use().Browser("firefox").Without("javascriptEnabled")) -// See: https://code.google.com/p/selenium/wiki/DesiredCapabilities -type Capabilities interface { - // Browser sets the desired browser name - {chrome|firefox|safari|iphone|...}. - Browser(browser string) Capabilities - - // Version sets the desired browser version (ex. "3.6"). - Version(version string) Capabilities - - // Platform sets the desired browser platform - {WINDOWS|XP|VISTA|MAC|LINUX|UNIX}. - Platform(platform string) Capabilities - - // With enables the provided feature (ex. "handlesAlerts"). - With(feature string) Capabilities - - // Without disables the provided feature (ex. "javascriptEnabled"). - Without(feature string) Capabilities - - // Custom sets a custom desired capability. - Custom(key string, value interface{}) Capabilities - - // JSON returns a JSON string representing the desired capabilities. - JSON() (string, error) -} - -// Use returns a Capabilities instance that can be passed to a page. -// All methods called on this instance will modify the original instance. -func Use() Capabilities { - return capabilities{} -} - -type capabilities map[string]interface{} - -func (c capabilities) Browser(browser string) Capabilities { - c["browserName"] = browser - return c -} - -func (c capabilities) Version(version string) Capabilities { - c["version"] = version - return c -} - -func (c capabilities) Platform(platform string) Capabilities { - c["platform"] = platform - return c -} - -func (c capabilities) With(feature string) Capabilities { - c[feature] = true - return c -} - -func (c capabilities) Without(feature string) Capabilities { - c[feature] = false - return c -} - -func (c capabilities) Custom(key string, value interface{}) Capabilities { - c[key] = value - return c -} - -func (c capabilities) JSON() (string, error) { - capabilitiesJSON, err := json.Marshal(c) - return string(capabilitiesJSON), err -} diff --git a/vendor/github.com/sclevine/agouti/core/capabilities_test.go b/vendor/github.com/sclevine/agouti/core/capabilities_test.go deleted file mode 100644 index c2487e1..0000000 --- a/vendor/github.com/sclevine/agouti/core/capabilities_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package core_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - . "github.com/sclevine/agouti/core" -) - -var _ = Describe("Capabilities", func() { - var capabilities Capabilities - - BeforeEach(func() { - capabilities = Use() - }) - - It("should successfully encode all provided options into JSON", func() { - capabilities.Browser("some-browser").Version("v100").Platform("some-os") - capabilities.With("enabledThing").Without("disabledThing") - capabilities.Custom("custom", "value") - Expect(capabilities.JSON()).To(MatchJSON(`{ - "browserName": "some-browser", - "version": "v100", - "platform": "some-os", - "enabledThing": true, - "disabledThing": false, - "custom": "value" - }`)) - }) - - Context("when the provided options cannot be converted to JSON", func() { - It("should return an error", func() { - capabilities.Custom("custom", func() {}) - _, err := capabilities.JSON() - Expect(err).To(MatchError("json: unsupported type: func()")) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/cookie.go b/vendor/github.com/sclevine/agouti/core/cookie.go deleted file mode 100644 index 14ae08c..0000000 --- a/vendor/github.com/sclevine/agouti/core/cookie.go +++ /dev/null @@ -1,10 +0,0 @@ -package core - -import "github.com/sclevine/agouti" - -// Cookie returns a agouti.Cookie instance with the provided name and value. -// This method, along with this entire package, is deprecated. It must return -// the new agouti.Cookie type to keep compatibility with the dsl package. -func Cookie(name string, value string) agouti.Cookie { - return agouti.Cookie{"name": name, "value": value} -} diff --git a/vendor/github.com/sclevine/agouti/core/core.go b/vendor/github.com/sclevine/agouti/core/core.go deleted file mode 100644 index df93dbb..0000000 --- a/vendor/github.com/sclevine/agouti/core/core.go +++ /dev/null @@ -1,86 +0,0 @@ -// Package core is DEPRECATED and will not receive future updates. -// Please use "github.com/sclevine/agouti" instead. -package core - -import ( - "fmt" - "os" - "time" - - "github.com/sclevine/agouti/api" -) - -func init() { - fmt.Fprintln(os.Stderr, `****************`) - fmt.Fprintln(os.Stderr, `NOTICE: "github.com/sclevine/agouti/core" has been deprecated in favor of "github.com/sclevine/agouti" and may soon perish.`) - fmt.Fprintln(os.Stderr, `Please switch to "github.com/sclevine/agouti" (which does not encorage dot-imports) as soon as possible.`) - fmt.Fprintln(os.Stderr, `****************`) -} - -// NewWebDriver returns an instance of a WebDriver specified by -// a templated URL and command. The URL should be the location of the -// WebDriver Wire Protocol web service brought up by the command. The -// command should be provided as a list of arguments (which are each -// templated). The optional timeout specifies how long to wait for the -// web service to become available. Default timeout is 5 seconds. -// -// Valid template parameters are: -// {{.Host}} - local address to bind to (usually 127.0.0.1) -// {{.Port}} - arbitrary free port on the local address -// {{.Address}} - {{.Host}}:{{.Port}} -// -// Selenium JAR example: -// command := []string{"java", "-jar", "selenium-server.jar", "-port", "{{.Port}}"} -// core.NewWebDriver("http://{{.Address}}/wd/hub", command) -func NewWebDriver(url string, command []string, timeout ...time.Duration) WebDriver { - apiWebDriver := api.NewWebDriver(url, command) - if len(timeout) > 0 { - apiWebDriver.Timeout = timeout[0] - } - return &webDriver{apiWebDriver} -} - -// ChromeDriver returns an instance of a ChromeDriver WebDriver. -func ChromeDriver() WebDriver { - return NewWebDriver("http://{{.Address}}", []string{"chromedriver", "--silent", "--port={{.Port}}"}) -} - -// PhantomJS returns an instance of a PhantomJS WebDriver. -// The return error is deprecated and will always be nil. -func PhantomJS() (WebDriver, error) { - return NewWebDriver("http://{{.Address}}", []string{"phantomjs", "--webdriver={{.Address}}"}), nil -} - -// Selenium returns an instance of a Selenium WebDriver. -// The return error is deprecated and will always be nil. -func Selenium() (WebDriver, error) { - return NewWebDriver("http://{{.Address}}/wd/hub", []string{"selenium-server", "-port", "{{.Port}}"}), nil -} - -// NewPage opens a Page using the provided WebDriver URL. -func NewPage(url string, desired Capabilities) (Page, error) { - session, err := api.Open(url, desired.(capabilities)) - if err != nil { - return nil, fmt.Errorf("failed to connect to WebDriver: %s", err) - } - return newPage(session), nil -} - -// SauceLabs opens a Sauce Labs session and returns a Page. Does not support Sauce Connect. -func SauceLabs(name, platform, browser, version, username, key string) (Page, error) { - url := "http://ondemand.saucelabs.com/wd/hub" - capabilities := capabilities{ - "name": name, - "platform": platform, - "browserName": browser, - "version": version, - "username": username, - "accessKey": key, - } - - session, err := api.Open(url, capabilities) - if err != nil { - return nil, fmt.Errorf("failed to open connection to Sauce Labs: %s", err) - } - return newPage(session), nil -} diff --git a/vendor/github.com/sclevine/agouti/core/deprecated.go b/vendor/github.com/sclevine/agouti/core/deprecated.go deleted file mode 100644 index 94438d6..0000000 --- a/vendor/github.com/sclevine/agouti/core/deprecated.go +++ /dev/null @@ -1,25 +0,0 @@ -package core - -import "time" - -// Chrome returns an instance of a ChromeDriver WebDriver. -// -// DEPRECATED: Use ChromeDriver instead. -func Chrome() (WebDriver, error) { - return ChromeDriver(), nil -} - -// Connect opens a Page using the provided WebDriver URL. -// -// DEPRECATED: Use NewPage instead. -func Connect(desired Capabilities, url string) (Page, error) { - return NewPage(url, desired) -} - -// CustomWebDriver returns an instance of a WebDriver specified by -// a templated URL and command. -// -// DEPRECATED: Use NewWebDriver instead. -func CustomWebDriver(url string, command []string, timeout ...time.Duration) WebDriver { - return NewWebDriver(url, command, timeout...) -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/integration/integration.go b/vendor/github.com/sclevine/agouti/core/internal/integration/integration.go deleted file mode 100644 index 76ab1b7..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/integration/integration.go +++ /dev/null @@ -1 +0,0 @@ -package integration diff --git a/vendor/github.com/sclevine/agouti/core/internal/integration/integration_suite_test.go b/vendor/github.com/sclevine/agouti/core/internal/integration/integration_suite_test.go deleted file mode 100644 index 10379ba..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/integration/integration_suite_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package integration_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - . "github.com/sclevine/agouti/core" -) - -var phantomDriver WebDriver - -func TestIntegration(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Integration Suite") -} - -var _ = BeforeSuite(func() { - phantomDriver, _ = PhantomJS() - Expect(phantomDriver.Start()).To(Succeed()) -}) - -var _ = AfterSuite(func() { - Expect(phantomDriver.Stop()).To(Succeed()) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/integration/integration_test.go b/vendor/github.com/sclevine/agouti/core/internal/integration/integration_test.go deleted file mode 100644 index 85ac803..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/integration/integration_test.go +++ /dev/null @@ -1,246 +0,0 @@ -package integration_test - -import ( - "io/ioutil" - "net/http" - "net/http/httptest" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - . "github.com/sclevine/agouti/core" - . "github.com/sclevine/agouti/matchers" -) - -var _ = Describe("Deprecated integration tests", func() { - var ( - page Page - submitted bool - server *httptest.Server - ) - - BeforeEach(func() { - server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) { - if request.Method == "POST" { - submitted = true - } - html, _ := ioutil.ReadFile("test_page.html") - response.Write(html) - })) - - var err error - page, err = phantomDriver.Page() - Expect(err).NotTo(HaveOccurred()) - Expect(page.Size(640, 480)).To(Succeed()) - Expect(page.Navigate(server.URL)).To(Succeed()) - }) - - AfterEach(func() { - page.Destroy() - server.Close() - }) - - It("should support finding the page title and URL", func() { - Expect(page).To(HaveTitle("Page Title")) - Expect(page).To(HaveURL(server.URL + "/")) - }) - - It("should support finding page elements", func() { - By("finding a header in the page", func() { - Expect(page.Find("header")).To(BeFound()) - Expect(page.Find("not-a-header")).NotTo(BeFound()) - }) - - By("finding text in the header", func() { - Expect(page.Find("header")).To(HaveText("Title")) - }) - - By("asserting that text is not in the header", func() { - Expect(page.Find("header")).NotTo(HaveText("Not-Title")) - }) - - By("referring to an element by selection index", func() { - Expect(page.All("option").At(0)).To(HaveText("first option")) - Expect(page.All("select").At(1).First("option")).To(HaveText("third option")) - }) - - By("matching text in the header", func() { - Expect(page.Find("header")).To(MatchText("T.+e")) - }) - - By("scoping selections by chaining", func() { - Expect(page.Find("header").Find("h1")).To(HaveText("Title")) - }) - - By("locating elements by XPath", func() { - Expect(page.Find("header").FindByXPath("//h1")).To(HaveText("Title")) - }) - - By("comparing two selections for equality", func() { - Expect(page.Find("#some_element")).To(EqualElement(page.FindByXPath("//div[@class='some-element']"))) - }) - }) - - It("should support selecting multiple elements", func() { - By("asserting on their state", func() { - Expect(page.All("select").All("option")).To(BeVisible()) - Expect(page.All("h1,h2")).NotTo(BeVisible()) - }) - }) - - It("should support finding form elements by label", func() { - By("finding an element by label text", func() { - Expect(page.FindByLabel("Some Label")).To(HaveAttribute("value", "some labeled value")) - }) - - By("finding an element embedded in a label", func() { - Expect(page.FindByLabel("Some Container Label")).To(HaveAttribute("value", "some embedded value")) - }) - }) - - It("should support finding button elements by text", func() { - By("finding a -Click Me -

Double-click Me

-
-
- -
- - - - - - - - - - - - diff --git a/vendor/github.com/sclevine/agouti/core/internal/mocks/bus.go b/vendor/github.com/sclevine/agouti/core/internal/mocks/bus.go deleted file mode 100644 index 1cdd15e..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/mocks/bus.go +++ /dev/null @@ -1,23 +0,0 @@ -package mocks - -import "encoding/json" - -type Bus struct { - SendCall struct { - Endpoint string - Method string - BodyJSON []byte - Result string - Err error - } -} - -func (b *Bus) Send(endpoint, method string, body interface{}, result ...interface{}) error { - b.SendCall.Endpoint = endpoint - b.SendCall.Method = method - b.SendCall.BodyJSON, _ = json.Marshal(body) - if len(result) > 0 { - json.Unmarshal([]byte(b.SendCall.Result), result[0]) - } - return b.SendCall.Err -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/mocks/element.go b/vendor/github.com/sclevine/agouti/core/internal/mocks/element.go deleted file mode 100644 index 115c3c6..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/mocks/element.go +++ /dev/null @@ -1,138 +0,0 @@ -package mocks - -import ( - "github.com/sclevine/agouti/api" -) - -type Element struct { - GetElementCall struct { - Selector api.Selector - ReturnElement *api.Element - Err error - } - - GetElementsCall struct { - Selector api.Selector - ReturnElements []*api.Element - Err error - } - - GetTextCall struct { - ReturnText string - Err error - } - - GetAttributeCall struct { - Attribute string - ReturnValue string - Err error - } - - GetCSSCall struct { - Property string - ReturnValue string - Err error - } - - ClickCall struct { - Called bool - Err error - } - - ClearCall struct { - Called bool - Err error - } - - ValueCall struct { - Text string - Err error - } - - IsSelectedCall struct { - ReturnSelected bool - Err error - } - - IsDisplayedCall struct { - ReturnDisplayed bool - Err error - } - - IsEnabledCall struct { - ReturnEnabled bool - Err error - } - - SubmitCall struct { - Called bool - Err error - } - - IsEqualToCall struct { - Element *api.Element - ReturnEquals bool - Err error - } -} - -func (e *Element) GetElement(selector api.Selector) (*api.Element, error) { - e.GetElementCall.Selector = selector - return e.GetElementCall.ReturnElement, e.GetElementCall.Err -} - -func (e *Element) GetElements(selector api.Selector) ([]*api.Element, error) { - e.GetElementsCall.Selector = selector - return e.GetElementsCall.ReturnElements, e.GetElementsCall.Err -} - -func (e *Element) GetText() (string, error) { - return e.GetTextCall.ReturnText, e.GetTextCall.Err -} - -func (e *Element) GetAttribute(attribute string) (string, error) { - e.GetAttributeCall.Attribute = attribute - return e.GetAttributeCall.ReturnValue, e.GetAttributeCall.Err -} - -func (e *Element) GetCSS(property string) (string, error) { - e.GetCSSCall.Property = property - return e.GetCSSCall.ReturnValue, e.GetCSSCall.Err -} - -func (e *Element) Click() error { - e.ClickCall.Called = true - return e.ClickCall.Err -} - -func (e *Element) Clear() error { - e.ClearCall.Called = true - return e.ClearCall.Err -} - -func (e *Element) Value(text string) error { - e.ValueCall.Text = text - return e.ValueCall.Err -} - -func (e *Element) IsSelected() (bool, error) { - return e.IsSelectedCall.ReturnSelected, e.IsSelectedCall.Err -} - -func (e *Element) IsDisplayed() (bool, error) { - return e.IsDisplayedCall.ReturnDisplayed, e.IsDisplayedCall.Err -} - -func (e *Element) IsEnabled() (bool, error) { - return e.IsEnabledCall.ReturnEnabled, e.IsEnabledCall.Err -} - -func (e *Element) Submit() error { - e.SubmitCall.Called = true - return e.SubmitCall.Err -} - -func (e *Element) IsEqualTo(other *api.Element) (bool, error) { - e.IsEqualToCall.Element = other - return e.IsEqualToCall.ReturnEquals, e.IsEqualToCall.Err -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/mocks/element_repository.go b/vendor/github.com/sclevine/agouti/core/internal/mocks/element_repository.go deleted file mode 100644 index 6740105..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/mocks/element_repository.go +++ /dev/null @@ -1,40 +0,0 @@ -package mocks - -import ( - "github.com/sclevine/agouti/core/internal/selection" -) - -type ElementRepository struct { - GetCall struct { - Selectors []selection.Selector - ReturnElements []selection.Element - Err error - } - - GetExactlyOneCall struct { - Selectors []selection.Selector - ReturnElement selection.Element - Err error - } - - GetAtLeastOneCall struct { - Selectors []selection.Selector - ReturnElements []selection.Element - Err error - } -} - -func (e *ElementRepository) Get(selectors []selection.Selector) ([]selection.Element, error) { - e.GetCall.Selectors = selectors - return e.GetCall.ReturnElements, e.GetCall.Err -} - -func (e *ElementRepository) GetExactlyOne(selectors []selection.Selector) (selection.Element, error) { - e.GetExactlyOneCall.Selectors = selectors - return e.GetExactlyOneCall.ReturnElement, e.GetExactlyOneCall.Err -} - -func (e *ElementRepository) GetAtLeastOne(selectors []selection.Selector) ([]selection.Element, error) { - e.GetAtLeastOneCall.Selectors = selectors - return e.GetAtLeastOneCall.ReturnElements, e.GetAtLeastOneCall.Err -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/mocks/session.go b/vendor/github.com/sclevine/agouti/core/internal/mocks/session.go deleted file mode 100644 index 6454f8e..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/mocks/session.go +++ /dev/null @@ -1,319 +0,0 @@ -package mocks - -import ( - "encoding/json" - - "github.com/sclevine/agouti/api" -) - -type Session struct { - GetElementCall struct { - Selector api.Selector - ReturnElement *api.Element - Err error - } - - GetElementsCall struct { - Selector api.Selector - ReturnElements []*api.Element - Err error - } - - GetActiveElementCall struct { - ReturnElement *api.Element - Err error - } - - DeleteCall struct { - Called bool - Err error - } - - GetWindowCall struct { - ReturnWindow *api.Window - Err error - } - - GetWindowsCall struct { - ReturnWindows []*api.Window - Err error - } - - SetWindowCall struct { - Window *api.Window - Err error - } - - SetWindowByNameCall struct { - Name string - Err error - } - - DeleteWindowCall struct { - Called bool - Err error - } - - GetScreenshotCall struct { - ReturnImage []byte - Err error - } - - SetCookieCall struct { - Cookie map[string]interface{} - Err error - } - - DeleteCookieCall struct { - Name string - Err error - } - - DeleteCookiesCall struct { - Called bool - Err error - } - - GetURLCall struct { - ReturnURL string - Err error - } - - SetURLCall struct { - URL string - Err error - } - - GetTitleCall struct { - ReturnTitle string - Err error - } - - GetSourceCall struct { - ReturnSource string - Err error - } - - DoubleClickCall struct { - Called bool - Err error - } - - MoveToCall struct { - Element *api.Element - Point api.Offset - Err error - } - - FrameCall struct { - Frame *api.Element - Err error - } - - FrameParentCall struct { - Called bool - Err error - } - - ExecuteCall struct { - Body string - Arguments []interface{} - Result string - Err error - } - - ForwardCall struct { - Called bool - Err error - } - - BackCall struct { - Called bool - Err error - } - - RefreshCall struct { - Called bool - Err error - } - - GetAlertTextCall struct { - ReturnText string - Err error - } - - SetAlertTextCall struct { - Text string - Err error - } - - AcceptAlertCall struct { - Called bool - Err error - } - - DismissAlertCall struct { - Called bool - Err error - } - - NewLogsCall struct { - LogType string - ReturnLogs []api.Log - Err error - } - - GetLogTypesCall struct { - ReturnTypes []string - Err error - } -} - -func (s *Session) Delete() error { - s.DeleteCall.Called = true - return s.DeleteCall.Err -} - -func (s *Session) GetElement(selector api.Selector) (*api.Element, error) { - s.GetElementCall.Selector = selector - return s.GetElementCall.ReturnElement, s.GetElementCall.Err -} - -func (s *Session) GetElements(selector api.Selector) ([]*api.Element, error) { - s.GetElementsCall.Selector = selector - return s.GetElementsCall.ReturnElements, s.GetElementsCall.Err -} - -func (s *Session) GetActiveElement() (*api.Element, error) { - return s.GetActiveElementCall.ReturnElement, s.GetActiveElementCall.Err -} - -func (s *Session) GetWindow() (*api.Window, error) { - return s.GetWindowCall.ReturnWindow, s.GetWindowCall.Err -} - -func (s *Session) GetWindows() ([]*api.Window, error) { - return s.GetWindowsCall.ReturnWindows, s.GetWindowsCall.Err -} - -func (s *Session) SetWindow(window *api.Window) error { - s.SetWindowCall.Window = window - return s.SetWindowCall.Err -} - -func (s *Session) SetWindowByName(name string) error { - s.SetWindowByNameCall.Name = name - return s.SetWindowByNameCall.Err -} - -func (s *Session) DeleteWindow() error { - s.DeleteWindowCall.Called = true - return s.DeleteWindowCall.Err -} - -func (s *Session) GetScreenshot() ([]byte, error) { - return s.GetScreenshotCall.ReturnImage, s.GetScreenshotCall.Err -} - -func (s *Session) SetCookie(cookie map[string]interface{}) error { - s.SetCookieCall.Cookie = cookie - return s.SetCookieCall.Err -} - -func (s *Session) DeleteCookie(name string) error { - s.DeleteCookieCall.Name = name - return s.DeleteCookieCall.Err -} - -func (s *Session) DeleteCookies() error { - s.DeleteCookiesCall.Called = true - return s.DeleteCookiesCall.Err -} - -func (s *Session) GetURL() (string, error) { - return s.GetURLCall.ReturnURL, s.GetURLCall.Err -} - -func (s *Session) SetURL(url string) error { - s.SetURLCall.URL = url - return s.SetURLCall.Err -} - -func (s *Session) GetTitle() (string, error) { - return s.GetTitleCall.ReturnTitle, s.GetTitleCall.Err -} - -func (s *Session) GetSource() (string, error) { - return s.GetSourceCall.ReturnSource, s.GetSourceCall.Err -} - -func (s *Session) DoubleClick() error { - s.DoubleClickCall.Called = true - return s.DoubleClickCall.Err -} - -func (s *Session) MoveTo(element *api.Element, point api.Offset) error { - s.MoveToCall.Element = element - s.MoveToCall.Point = point - return s.MoveToCall.Err -} - -func (s *Session) Frame(frame *api.Element) error { - s.FrameCall.Frame = frame - return s.FrameCall.Err -} - -func (s *Session) FrameParent() error { - s.FrameParentCall.Called = true - return s.FrameParentCall.Err -} - -func (s *Session) Execute(body string, arguments []interface{}, result interface{}) error { - s.ExecuteCall.Body = body - s.ExecuteCall.Arguments = arguments - json.Unmarshal([]byte(s.ExecuteCall.Result), result) - return s.ExecuteCall.Err -} - -func (s *Session) Forward() error { - s.ForwardCall.Called = true - return s.ForwardCall.Err -} - -func (s *Session) Back() error { - s.BackCall.Called = true - return s.BackCall.Err -} - -func (s *Session) Refresh() error { - s.RefreshCall.Called = true - return s.RefreshCall.Err -} - -func (s *Session) GetAlertText() (string, error) { - return s.GetAlertTextCall.ReturnText, s.GetAlertTextCall.Err -} - -func (s *Session) SetAlertText(text string) error { - s.SetAlertTextCall.Text = text - return s.SetAlertTextCall.Err -} - -func (s *Session) AcceptAlert() error { - s.AcceptAlertCall.Called = true - return s.AcceptAlertCall.Err -} - -func (s *Session) DismissAlert() error { - s.DismissAlertCall.Called = true - return s.DismissAlertCall.Err -} - -func (s *Session) NewLogs(logType string) ([]api.Log, error) { - s.NewLogsCall.LogType = logType - return s.NewLogsCall.ReturnLogs, s.NewLogsCall.Err -} - -func (s *Session) GetLogTypes() ([]string, error) { - return s.GetLogTypesCall.ReturnTypes, s.GetLogTypesCall.Err -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/mocks/webdriver.go b/vendor/github.com/sclevine/agouti/core/internal/mocks/webdriver.go deleted file mode 100644 index 4a37805..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/mocks/webdriver.go +++ /dev/null @@ -1,35 +0,0 @@ -package mocks - -import "github.com/sclevine/agouti/api" - -type WebDriver struct { - OpenCall struct { - Desired map[string]interface{} - ReturnSession *api.Session - Err error - } - - StartCall struct { - Called bool - Err error - } - - StopCall struct { - Called bool - Err error - } -} - -func (w *WebDriver) Open(desired map[string]interface{}) (*api.Session, error) { - return w.OpenCall.ReturnSession, w.OpenCall.Err -} - -func (w *WebDriver) Start() error { - w.StartCall.Called = true - return w.StartCall.Err -} - -func (w *WebDriver) Stop() error { - w.StopCall.Called = true - return w.StopCall.Err -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/page/page.go b/vendor/github.com/sclevine/agouti/core/internal/page/page.go deleted file mode 100644 index 8cf8466..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/page/page.go +++ /dev/null @@ -1,348 +0,0 @@ -package page - -import ( - "fmt" - "os" - "path/filepath" - "regexp" - "sort" - "strings" - "time" - - "github.com/sclevine/agouti" - "github.com/sclevine/agouti/api" -) - -type Page struct { - Session interface { - Delete() error - GetWindow() (*api.Window, error) - GetWindows() ([]*api.Window, error) - SetWindow(window *api.Window) error - SetWindowByName(name string) error - DeleteWindow() error - GetScreenshot() ([]byte, error) - SetCookie(cookie map[string]interface{}) error - DeleteCookie(name string) error - DeleteCookies() error - GetURL() (string, error) - SetURL(url string) error - GetTitle() (string, error) - GetSource() (string, error) - Frame(frame *api.Element) error - FrameParent() error - Execute(body string, arguments []interface{}, result interface{}) error - Forward() error - Back() error - Refresh() error - GetAlertText() (string, error) - SetAlertText(text string) error - AcceptAlert() error - DismissAlert() error - NewLogs(logType string) ([]api.Log, error) - GetLogTypes() ([]string, error) - } - logs map[string][]Log -} - -type Log struct { - Message string - Location string - Level string - Time time.Time -} - -func (p *Page) Destroy() error { - if err := p.Session.Delete(); err != nil { - return fmt.Errorf("failed to destroy session: %s", err) - } - return nil -} - -func (p *Page) Navigate(url string) error { - if err := p.Session.SetURL(url); err != nil { - return fmt.Errorf("failed to navigate: %s", err) - } - return nil -} - -func (p *Page) SetCookie(cookie map[string]interface{}) error { - if err := p.Session.SetCookie(cookie); err != nil { - return fmt.Errorf("failed to set cookie: %s", err) - } - return nil -} - -func (p *Page) DeleteCookie(name string) error { - if err := p.Session.DeleteCookie(name); err != nil { - return fmt.Errorf("failed to delete cookie %s: %s", name, err) - } - return nil -} - -func (p *Page) ClearCookies() error { - if err := p.Session.DeleteCookies(); err != nil { - return fmt.Errorf("failed to clear cookies: %s", err) - } - return nil -} - -func (p *Page) URL() (string, error) { - url, err := p.Session.GetURL() - if err != nil { - return "", fmt.Errorf("failed to retrieve URL: %s", err) - } - return url, nil -} - -func (p *Page) Size(width, height int) error { - window, err := p.Session.GetWindow() - if err != nil { - return fmt.Errorf("failed to retrieve window: %s", err) - } - - if err := window.SetSize(width, height); err != nil { - return fmt.Errorf("failed to set window size: %s", err) - } - - return nil -} - -func (p *Page) Screenshot(filename string) error { - if err := os.MkdirAll(filepath.Dir(filename), 0750); err != nil { - return fmt.Errorf("failed to create directory for screenshot: %s", err) - } - - file, err := os.Create(filename) - if err != nil { - return fmt.Errorf("failed to create file for screenshot: %s", err) - } - defer file.Close() - - screenshot, err := p.Session.GetScreenshot() - if err != nil { - os.Remove(filename) - return fmt.Errorf("failed to retrieve screenshot: %s", err) - } - - if _, err := file.Write(screenshot); err != nil { - return fmt.Errorf("failed to write file for screenshot: %s", err) - } - - return nil -} - -func (p *Page) Title() (string, error) { - title, err := p.Session.GetTitle() - if err != nil { - return "", fmt.Errorf("failed to retrieve page title: %s", err) - } - return title, nil -} - -func (p *Page) HTML() (string, error) { - html, err := p.Session.GetSource() - if err != nil { - return "", fmt.Errorf("failed to retrieve page HTML: %s", err) - } - return html, nil -} - -func (p *Page) RunScript(body string, arguments map[string]interface{}, result interface{}) error { - var ( - keys []string - values []interface{} - ) - - for key, value := range arguments { - keys = append(keys, key) - values = append(values, value) - } - - argumentList := strings.Join(keys, ", ") - cleanBody := fmt.Sprintf("return (function(%s) { %s; }).apply(this, arguments);", argumentList, body) - - if err := p.Session.Execute(cleanBody, values, result); err != nil { - return fmt.Errorf("failed to run script: %s", err) - } - - return nil -} - -func (p *Page) PopupText() (string, error) { - text, err := p.Session.GetAlertText() - if err != nil { - return "", fmt.Errorf("failed to retrieve popup text: %s", err) - } - return text, nil -} - -func (p *Page) EnterPopupText(text string) error { - if err := p.Session.SetAlertText(text); err != nil { - return fmt.Errorf("failed to enter popup text: %s", err) - } - return nil -} - -func (p *Page) ConfirmPopup() error { - if err := p.Session.AcceptAlert(); err != nil { - return fmt.Errorf("failed to confirm popup: %s", err) - } - return nil -} - -func (p *Page) CancelPopup() error { - if err := p.Session.DismissAlert(); err != nil { - return fmt.Errorf("failed to cancel popup: %s", err) - } - return nil -} - -func (p *Page) Forward() error { - if err := p.Session.Forward(); err != nil { - return fmt.Errorf("failed to navigate forward in history: %s", err) - } - return nil -} - -func (p *Page) Back() error { - if err := p.Session.Back(); err != nil { - return fmt.Errorf("failed to navigate backwards in history: %s", err) - } - return nil -} - -func (p *Page) Refresh() error { - if err := p.Session.Refresh(); err != nil { - return fmt.Errorf("failed to refresh page: %s", err) - } - return nil -} - -func (p *Page) SwitchToParentFrame() error { - if err := p.Session.FrameParent(); err != nil { - return fmt.Errorf("failed to switch to parent frame: %s", err) - } - return nil -} - -func (p *Page) SwitchToRootFrame() error { - if err := p.Session.Frame(nil); err != nil { - return fmt.Errorf("failed to switch to original page frame: %s", err) - } - return nil -} - -func (p *Page) SwitchToWindow(name string) error { - if err := p.Session.SetWindowByName(name); err != nil { - return fmt.Errorf("failed to switch to named window: %s", err) - } - return nil -} - -func (p *Page) NextWindow() error { - windows, err := p.Session.GetWindows() - if err != nil { - return fmt.Errorf("failed to find available windows: %s", err) - } - - var windowIDs []string - for _, window := range windows { - windowIDs = append(windowIDs, window.ID) - } - - // order not defined according to W3 spec - sort.Strings(windowIDs) - - activeWindow, err := p.Session.GetWindow() - if err != nil { - return fmt.Errorf("failed to find active window: %s", err) - } - - for position, windowID := range windowIDs { - if windowID == activeWindow.ID { - activeWindow.ID = windowIDs[(position+1)%len(windowIDs)] - break - } - } - - if err := p.Session.SetWindow(activeWindow); err != nil { - return fmt.Errorf("failed to change active window: %s", err) - } - - return nil -} - -func (p *Page) CloseWindow() error { - if err := p.Session.DeleteWindow(); err != nil { - return fmt.Errorf("failed to close active window: %s", err) - } - return nil -} - -func (p *Page) WindowCount() (int, error) { - windows, err := p.Session.GetWindows() - if err != nil { - return 0, fmt.Errorf("failed to find available windows: %s", err) - } - return len(windows), nil -} - -func (p *Page) LogTypes() ([]string, error) { - types, err := p.Session.GetLogTypes() - if err != nil { - return nil, fmt.Errorf("failed to retrieve log types: %s", err) - } - return types, nil -} - -func (p *Page) ReadLogs(logType string, all ...bool) ([]Log, error) { - if p.logs == nil { - p.logs = map[string][]Log{} - } - - clientLogs, err := p.Session.NewLogs(logType) - if err != nil { - return nil, fmt.Errorf("failed to retrieve logs: %s", err) - } - - messageMatcher := regexp.MustCompile(`^(?s:(.+))\s\(([^)]*:\w*)\)$`) - - var logs []Log - for _, clientLog := range clientLogs { - matches := messageMatcher.FindStringSubmatch(clientLog.Message) - message, location := clientLog.Message, "" - if len(matches) > 2 { - message, location = matches[1], matches[2] - } - - log := Log{message, location, clientLog.Level, msToTime(clientLog.Timestamp)} - logs = append(logs, log) - } - p.logs[logType] = append(p.logs[logType], logs...) - - if len(all) > 0 && all[0] { - return p.logs[logType], nil - } - - return logs, nil -} - -// Patch to allow Page to work with new matchers after core deprecation -func (p *Page) ReadAllLogs(logType string) ([]agouti.Log, error) { - coreLogs, err := p.ReadLogs(logType, true) - if err != nil { - return nil, err - } - var agoutiLogs []agouti.Log - for _, log := range coreLogs { - agoutiLogs = append(agoutiLogs, agouti.Log(log)) - } - return agoutiLogs, nil -} - -func msToTime(ms int64) time.Time { - seconds := ms / 1000 - nanoseconds := (ms % 1000) * 1000000 - return time.Unix(seconds, nanoseconds) -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/page/page_suite_test.go b/vendor/github.com/sclevine/agouti/core/internal/page/page_suite_test.go deleted file mode 100644 index ba64db4..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/page/page_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package page_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestPage(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Page Suite") -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/page/page_test.go b/vendor/github.com/sclevine/agouti/core/internal/page/page_test.go deleted file mode 100644 index 5febdb0..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/page/page_test.go +++ /dev/null @@ -1,549 +0,0 @@ -package page_test - -import ( - "errors" - "io/ioutil" - "os" - "path/filepath" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/page" -) - -var _ = Describe("Page", func() { - var ( - page *Page - session *mocks.Session - ) - - BeforeEach(func() { - session = &mocks.Session{} - page = &Page{Session: session} - }) - - Describe("#Destroy", func() { - It("should successfully delete the session", func() { - Expect(page.Destroy()).To(Succeed()) - Expect(session.DeleteCall.Called).To(BeTrue()) - }) - - Context("when deleting the session fails", func() { - It("should return an error", func() { - session.DeleteCall.Err = errors.New("some error") - Expect(page.Destroy()).To(MatchError("failed to destroy session: some error")) - }) - }) - }) - - Describe("#Navigate", func() { - It("should successfully instruct the session to navigate to the provided URL", func() { - Expect(page.Navigate("http://example.com")).To(Succeed()) - Expect(session.SetURLCall.URL).To(Equal("http://example.com")) - }) - - Context("when the navigate fails", func() { - It("should return an error", func() { - session.SetURLCall.Err = errors.New("some error") - Expect(page.Navigate("http://example.com")).To(MatchError("failed to navigate: some error")) - }) - }) - }) - - Describe("#SetCookie", func() { - It("should successfully instruct the session to add the cookie to the session", func() { - cookie := map[string]interface{}{"some": "cookie"} - Expect(page.SetCookie(cookie)).To(Succeed()) - Expect(session.SetCookieCall.Cookie).To(Equal(cookie)) - }) - - Context("when the session fails to set the cookie", func() { - It("should return an error", func() { - session.SetCookieCall.Err = errors.New("some error") - err := page.SetCookie(map[string]interface{}{}) - Expect(err).To(MatchError("failed to set cookie: some error")) - }) - }) - }) - - Describe("#DeleteCookie", func() { - It("should successfully instruct the session to delete a named cookie", func() { - Expect(page.DeleteCookie("some-name")).To(Succeed()) - Expect(session.DeleteCookieCall.Name).To(Equal("some-name")) - }) - - Context("when deleting the named cookie fails", func() { - It("should return an error", func() { - session.DeleteCookieCall.Err = errors.New("some error") - Expect(page.DeleteCookie("some-name")).To(MatchError("failed to delete cookie some-name: some error")) - }) - }) - }) - - Describe("#ClearCookies", func() { - It("should successfully instruct the session to delete all cookies", func() { - Expect(page.ClearCookies()).To(Succeed()) - Expect(session.DeleteCookiesCall.Called).To(BeTrue()) - }) - - Context("when deleting all cookies fails", func() { - It("should return an error", func() { - session.DeleteCookiesCall.Err = errors.New("some error") - Expect(page.ClearCookies()).To(MatchError("failed to clear cookies: some error")) - }) - }) - }) - - Describe("#URL", func() { - It("should successfully return the URL of the current page", func() { - session.GetURLCall.ReturnURL = "http://example.com" - url, err := page.URL() - Expect(url).To(Equal("http://example.com")) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("when the session fails to retrieve the URL", func() { - It("should return an error", func() { - session.GetURLCall.Err = errors.New("some error") - _, err := page.URL() - Expect(err).To(MatchError("failed to retrieve URL: some error")) - }) - }) - }) - - Describe("#Size", func() { - var ( - bus *mocks.Bus - window *api.Window - ) - - BeforeEach(func() { - bus = &mocks.Bus{} - window = &api.Window{Session: &api.Session{Bus: bus}} - }) - - It("should set the window width and height to the provided dimensions", func() { - session.GetWindowCall.ReturnWindow = window - Expect(page.Size(640, 480)).To(Succeed()) - Expect(bus.SendCall.BodyJSON).To(MatchJSON(`{"width": 640, "height": 480}`)) - }) - - Context("when the session fails to retrieve a window", func() { - It("should return an error", func() { - session.GetWindowCall.Err = errors.New("some error") - Expect(page.Size(640, 480)).To(MatchError("failed to retrieve window: some error")) - }) - }) - - Context("when the window fails to retrieve its size", func() { - It("should return an error", func() { - session.GetWindowCall.ReturnWindow = window - bus.SendCall.Err = errors.New("some error") - Expect(page.Size(640, 480)).To(MatchError("failed to set window size: some error")) - }) - }) - }) - - Describe("#Screenshot", func() { - var filename string - - BeforeEach(func() { - directory, _ := os.Getwd() - filename = filepath.Join(directory, ".test.screenshot.png") - }) - - Context("when the file path cannot be constructed", func() { - It("should return an error", func() { - err := page.Screenshot("\000/a") // try NUL - Expect(err).To(MatchError("failed to create directory for screenshot: mkdir \x00: invalid argument")) - }) - }) - - Context("when a new screenshot file cannot be created", func() { - It("should return an error", func() { - err := page.Screenshot("") - Expect(err).To(MatchError("failed to create file for screenshot: open : no such file or directory")) - }) - }) - - Context("when the session fails to retrieve a screenshot", func() { - BeforeEach(func() { - session.GetScreenshotCall.Err = errors.New("some error") - }) - - It("should return an error indicating so", func() { - Expect(page.Screenshot(filename)).To(MatchError("failed to retrieve screenshot: some error")) - }) - - It("should remove the newly-created file", func() { - page.Screenshot(filename) - _, err := os.Stat(filename) - Expect(err).To(HaveOccurred()) - }) - }) - - Context("when the screenshot cannot be written to a file", func() { - // NOTE: would need to cause write-error to test - }) - - Context("when a screenshot is successfully written to a file", func() { - It("should successfully saves the screenshot", func() { - session.GetScreenshotCall.ReturnImage = []byte("some-image") - Expect(page.Screenshot(filename)).To(Succeed()) - defer os.Remove(filename) - result, _ := ioutil.ReadFile(filename) - Expect(string(result)).To(Equal("some-image")) - }) - }) - }) - - Describe("#Title", func() { - It("should successfully return the title of the current page", func() { - session.GetTitleCall.ReturnTitle = "Some Title" - title, err := page.Title() - Expect(title).To(Equal("Some Title")) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("when the session fails to retrieve the page title", func() { - It("should return an error", func() { - session.GetTitleCall.Err = errors.New("some error") - _, err := page.Title() - Expect(err).To(MatchError("failed to retrieve page title: some error")) - }) - }) - }) - - Describe("#HTML", func() { - It("should return the HTML of the current page", func() { - session.GetSourceCall.ReturnSource = "Some HTML" - html, err := page.HTML() - Expect(html).To(Equal("Some HTML")) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("when the session fails to retrieve the page HTML", func() { - It("should return an error", func() { - session.GetSourceCall.Err = errors.New("some error") - _, err := page.HTML() - Expect(err).To(MatchError("failed to retrieve page HTML: some error")) - }) - }) - }) - - Describe("#RunScript", func() { - var ( - result struct{ Some string } - err error - ) - - BeforeEach(func() { - session.ExecuteCall.Result = `{"some": "result"}` - err = page.RunScript("some javascript code", map[string]interface{}{"argument": "value"}, &result) - }) - - It("should provide the session with an argument-provided javascript function", func() { - Expect(session.ExecuteCall.Body).To(Equal("return (function(argument) { some javascript code; }).apply(this, arguments);")) - }) - - It("should provide the session with arguments to call the provided function with", func() { - Expect(session.ExecuteCall.Arguments).To(Equal([]interface{}{"value"})) - }) - - It("should unmarshall the returned result into the provided result interface", func() { - Expect(result.Some).To(Equal("result")) - }) - - It("should be successful", func() { - Expect(err).ToNot(HaveOccurred()) - }) - - Context("when running the script fails", func() { - It("should return the session error", func() { - session.ExecuteCall.Err = errors.New("some error") - err = page.RunScript("", map[string]interface{}{}, &result) - Expect(err).To(MatchError("failed to run script: some error")) - }) - }) - }) - - Describe("#PopupText", func() { - It("should return the popup text of the popup and succeed", func() { - session.GetAlertTextCall.ReturnText = "some popup text" - text, err := page.PopupText() - Expect(text).To(Equal("some popup text")) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("when the session fails to retrieve the page popup text", func() { - It("should return an error", func() { - session.GetAlertTextCall.Err = errors.New("some error") - _, err := page.PopupText() - Expect(err).To(MatchError("failed to retrieve popup text: some error")) - }) - }) - }) - - Describe("#EnterPopupText", func() { - It("should provide the session with the text to enter and succeed", func() { - Expect(page.EnterPopupText("some text")).To(Succeed()) - Expect(session.SetAlertTextCall.Text).To(Equal("some text")) - }) - - Context("when the session fails to enter the page popup text", func() { - It("should return an error", func() { - session.SetAlertTextCall.Err = errors.New("some error") - Expect(page.EnterPopupText("some text")).To(MatchError("failed to enter popup text: some error")) - }) - }) - }) - - Describe("#ConfirmPopup", func() { - It("should instruct the session to confirm an alert", func() { - Expect(page.ConfirmPopup()).To(Succeed()) - Expect(session.AcceptAlertCall.Called).To(BeTrue()) - }) - - Context("when the session fails to confirm an alert", func() { - It("should return an error", func() { - session.AcceptAlertCall.Err = errors.New("some error") - Expect(page.ConfirmPopup()).To(MatchError("failed to confirm popup: some error")) - }) - }) - }) - - Describe("#CancelPopup", func() { - It("should instruct the session to cancel an alert", func() { - Expect(page.CancelPopup()).To(Succeed()) - Expect(session.DismissAlertCall.Called).To(BeTrue()) - }) - - Context("when the session fails to cancel an alert", func() { - It("should return an error", func() { - session.DismissAlertCall.Err = errors.New("some error") - Expect(page.CancelPopup()).To(MatchError("failed to cancel popup: some error")) - }) - }) - }) - - Describe("#Forward", func() { - It("should successfully instruct the session to move forward in history", func() { - Expect(page.Forward()).To(Succeed()) - Expect(session.ForwardCall.Called).To(BeTrue()) - }) - - Context("when navigating forward fails", func() { - It("should return an error", func() { - session.ForwardCall.Err = errors.New("some error") - Expect(page.Forward()).To(MatchError("failed to navigate forward in history: some error")) - }) - }) - }) - - Describe("#Back", func() { - It("should successfully instruct the session to move back in history", func() { - Expect(page.Back()).To(Succeed()) - Expect(session.BackCall.Called).To(BeTrue()) - }) - - Context("when navigating back fails", func() { - It("should return an error", func() { - session.BackCall.Err = errors.New("some error") - Expect(page.Back()).To(MatchError("failed to navigate backwards in history: some error")) - }) - }) - }) - - Describe("#Refresh", func() { - It("should successfully instruct the session to refresh", func() { - Expect(page.Refresh()).To(Succeed()) - Expect(session.RefreshCall.Called).To(BeTrue()) - }) - - Context("when refreshing the page fails", func() { - It("should return an error", func() { - session.RefreshCall.Err = errors.New("some error") - Expect(page.Refresh()).To(MatchError("failed to refresh page: some error")) - }) - }) - }) - - Describe("#SwitchToParentFrame", func() { - It("should successfully instruct the session to change focus to the parent frame", func() { - Expect(page.SwitchToParentFrame()).To(Succeed()) - Expect(session.FrameParentCall.Called).To(BeTrue()) - }) - - Context("when switching to the parent frame fails", func() { - It("should return an error", func() { - session.FrameParentCall.Err = errors.New("some error") - Expect(page.SwitchToParentFrame()).To(MatchError("failed to switch to parent frame: some error")) - }) - }) - }) - - Describe("#SwitchToRootFrame", func() { - It("should successfully instruct the session to change focus to the root frame", func() { - session.FrameCall.Frame = &api.Element{} - Expect(page.SwitchToRootFrame()).To(Succeed()) - Expect(session.FrameCall.Frame).To(BeNil()) - }) - - Context("when switching to the root frame fails", func() { - It("should return an error", func() { - session.FrameCall.Err = errors.New("some error") - Expect(page.SwitchToRootFrame()).To(MatchError("failed to switch to original page frame: some error")) - }) - }) - }) - - Describe("#SwitchToWindow", func() { - It("should successfully instruct the session to switch to the named window", func() { - Expect(page.SwitchToWindow("some name")).To(Succeed()) - Expect(session.SetWindowByNameCall.Name).To(Equal("some name")) - }) - - Context("when switching to the root frame fails", func() { - It("should return an error", func() { - session.SetWindowByNameCall.Err = errors.New("some error") - Expect(page.SwitchToWindow("some name")).To(MatchError("failed to switch to named window: some error")) - }) - }) - }) - - Describe("#NextWindow", func() { - BeforeEach(func() { - firstWindow := &api.Window{ID: "first window"} - secondWindow := &api.Window{ID: "second window"} - thirdWindow := &api.Window{ID: "third window"} - session.GetWindowsCall.ReturnWindows = []*api.Window{secondWindow, firstWindow, thirdWindow} - session.GetWindowCall.ReturnWindow = firstWindow - }) - - It("should successfully instruct the session to switch to the next window in sorted order", func() { - Expect(page.NextWindow()).To(Succeed()) - Expect(session.SetWindowCall.Window.ID).To(Equal("second window")) - }) - - Context("when retrieving the available windows fails", func() { - It("should return an error", func() { - session.GetWindowsCall.Err = errors.New("some error") - Expect(page.NextWindow()).To(MatchError("failed to find available windows: some error")) - }) - }) - - Context("when retrieving the active window fails", func() { - It("should return an error", func() { - session.GetWindowCall.Err = errors.New("some error") - Expect(page.NextWindow()).To(MatchError("failed to find active window: some error")) - }) - }) - - Context("when setting the active window fails", func() { - It("should return an error", func() { - session.SetWindowCall.Err = errors.New("some error") - Expect(page.NextWindow()).To(MatchError("failed to change active window: some error")) - }) - }) - }) - - Describe("#CloseWindow", func() { - It("should successfully instruct the session to close the active window", func() { - Expect(page.CloseWindow()).To(Succeed()) - Expect(session.DeleteWindowCall.Called).To(BeTrue()) - }) - - Context("when closing the active window fails", func() { - It("should return an error", func() { - session.DeleteWindowCall.Err = errors.New("some error") - Expect(page.CloseWindow()).To(MatchError("failed to close active window: some error")) - }) - }) - }) - - Describe("#WindowCount", func() { - It("should successfully return the number of windows from the session", func() { - session.GetWindowsCall.ReturnWindows = []*api.Window{&api.Window{}, &api.Window{}} - Expect(page.WindowCount()).To(Equal(2)) - }) - - Context("when retrieving the available windows fails", func() { - It("should return an error", func() { - session.GetWindowsCall.Err = errors.New("some error") - _, err := page.WindowCount() - Expect(err).To(MatchError("failed to find available windows: some error")) - }) - }) - }) - - Describe("#ReadLogs", func() { - It("should request logs of the provided log type from the session", func() { - _, err := page.ReadLogs("some type") - Expect(err).To(Succeed()) - Expect(session.NewLogsCall.LogType).To(Equal("some type")) - }) - - Context("when the session fails to retrieve logs", func() { - It("should return an error", func() { - session.NewLogsCall.Err = errors.New("some error") - _, err := page.ReadLogs("some type") - Expect(err).To(MatchError("failed to retrieve logs: some error")) - }) - }) - - Describe("returned logs", func() { - BeforeEach(func() { - session.NewLogsCall.ReturnLogs = []api.Log{api.Log{"old log", "old level", 1418196096123}} - page.ReadLogs("some type") - session.NewLogsCall.ReturnLogs = []api.Log{ - api.Log{"new log (1:22)", "new level", 1418196097543}, - api.Log{"newer log (:)", "newer level", 1418196098376}, - } - }) - - Context("when only new logs are requested", func() { - It("should return new logs with the correct time and code location", func() { - logs, err := page.ReadLogs("some type") - Expect(err).NotTo(HaveOccurred()) - Expect(logs).To(HaveLen(2)) - Expect(logs[0].Message).To(Equal("new log")) - Expect(logs[0].Location).To(Equal("1:22")) - Expect(logs[0].Level).To(Equal("new level")) - Expect(logs[0].Time.Unix()).To(BeEquivalentTo(1418196097)) - Expect(logs[1].Message).To(Equal("newer log")) - Expect(logs[1].Location).To(Equal(":")) - Expect(logs[1].Level).To(Equal("newer level")) - Expect(logs[1].Time.Unix()).To(BeEquivalentTo(1418196098)) - }) - }) - - Context("when all logs are requested", func() { - It("should return all logs", func() { - logs, err := page.ReadLogs("some type", true) - Expect(err).NotTo(HaveOccurred()) - Expect(logs).To(HaveLen(3)) - Expect(logs[0].Message).To(Equal("old log")) - Expect(logs[1].Message).To(Equal("new log")) - Expect(logs[2].Message).To(Equal("newer log")) - }) - }) - }) - }) - - Describe("#LogTypes", func() { - It("should successfully return the log types", func() { - session.GetLogTypesCall.ReturnTypes = []string{"first type", "second type"} - Expect(page.LogTypes()).To(Equal([]string{"first type", "second type"})) - }) - - Context("when the session fails to retrieve the log types", func() { - It("should return an error", func() { - session.GetLogTypesCall.Err = errors.New("some error") - _, err := page.LogTypes() - Expect(err).To(MatchError("failed to retrieve log types: some error")) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/actions.go b/vendor/github.com/sclevine/agouti/core/internal/selection/actions.go deleted file mode 100644 index 6fb14c4..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/actions.go +++ /dev/null @@ -1,120 +0,0 @@ -package selection - -import ( - "fmt" - - "github.com/sclevine/agouti/api" -) - -type actionsFunc func(Element) error - -func (s *Selection) forEachElement(actions actionsFunc) error { - elements, err := s.Elements.GetAtLeastOne(s.selectors) - if err != nil { - return fmt.Errorf("failed to select '%s': %s", s, err) - } - - for _, element := range elements { - if err := actions(element); err != nil { - return err - } - } - return nil -} - -func (s *Selection) Click() error { - return s.forEachElement(func(element Element) error { - if err := element.Click(); err != nil { - return fmt.Errorf("failed to click on '%s': %s", s, err) - } - return nil - }) -} - -func (s *Selection) DoubleClick() error { - return s.forEachElement(func(element Element) error { - if err := s.Session.MoveTo(element.(*api.Element), nil); err != nil { - return fmt.Errorf("failed to move mouse to '%s': %s", s, err) - } - if err := s.Session.DoubleClick(); err != nil { - return fmt.Errorf("failed to double-click on '%s': %s", s, err) - } - return nil - }) -} - -func (s *Selection) Fill(text string) error { - return s.forEachElement(func(element Element) error { - if err := element.Clear(); err != nil { - return fmt.Errorf("failed to clear '%s': %s", s, err) - } - if err := element.Value(text); err != nil { - return fmt.Errorf("failed to enter text into '%s': %s", s, err) - } - return nil - }) -} - -func (s *Selection) Check() error { - return s.setChecked(true) -} - -func (s *Selection) Uncheck() error { - return s.setChecked(false) -} - -func (s *Selection) setChecked(checked bool) error { - return s.forEachElement(func(element Element) error { - elementType, err := element.GetAttribute("type") - if err != nil { - return fmt.Errorf("failed to retrieve type of '%s': %s", s, err) - } - - if elementType != "checkbox" { - return fmt.Errorf("'%s' does not refer to a checkbox", s) - } - - selected, err := element.IsSelected() - if err != nil { - return fmt.Errorf("failed to retrieve state of '%s': %s", s, err) - } - - if selected != checked { - if err := element.Click(); err != nil { - return fmt.Errorf("failed to click on '%s': %s", s, err) - } - } - return nil - }) -} - -func (s *Selection) Select(text string) error { - return s.forEachElement(func(element Element) error { - optionXPath := fmt.Sprintf(`./option[normalize-space()="%s"]`, text) - optionToSelect := Selector{Type: "xpath", Value: optionXPath} - options, err := element.GetElements(optionToSelect.API()) - if err != nil { - return fmt.Errorf("failed to select specified option for some '%s': %s", s, err) - } - - if len(options) == 0 { - return fmt.Errorf(`no options with text "%s" found for some '%s'`, text, s) - } - - for _, option := range options { - if err := option.Click(); err != nil { - return fmt.Errorf(`failed to click on option with text "%s" for some '%s': %s`, text, s, err) - } - } - return nil - }) -} - -func (s *Selection) Submit() error { - return s.forEachElement(func(element Element) error { - if err := element.Submit(); err != nil { - return fmt.Errorf("failed to submit '%s': %s", s, err) - } - return nil - }) -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/actions_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/actions_test.go deleted file mode 100644 index 40a245d..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/actions_test.go +++ /dev/null @@ -1,297 +0,0 @@ -package selection_test - -import ( - "errors" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/selection" -) - -var _ = Describe("Actions", func() { - var ( - selection *Selection - session *mocks.Session - elementRepository *mocks.ElementRepository - firstElement *mocks.Element - secondElement *mocks.Element - ) - - BeforeEach(func() { - session = &mocks.Session{} - firstElement = &mocks.Element{} - secondElement = &mocks.Element{} - elementRepository = &mocks.ElementRepository{} - emptySelection := &Selection{Session: session, Elements: elementRepository} - selection = emptySelection.AppendCSS("#selector") - elementRepository.GetAtLeastOneCall.ReturnElements = []Element{firstElement, secondElement} - }) - - Describe("#Click", func() { - It("should successfully click on all selected elements", func() { - Expect(selection.Click()).To(Succeed()) - Expect(firstElement.ClickCall.Called).To(BeTrue()) - Expect(secondElement.ClickCall.Called).To(BeTrue()) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.Click()).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when any click fails", func() { - It("should return an error", func() { - secondElement.ClickCall.Err = errors.New("some error") - Expect(selection.Click()).To(MatchError("failed to click on 'CSS: #selector': some error")) - }) - }) - }) - - // TODO: extend mock to test multiple calls - Describe("#DoubleClick", func() { - var apiElement *api.Element - - BeforeEach(func() { - apiElement = &api.Element{} - elementRepository.GetAtLeastOneCall.ReturnElements = []Element{&api.Element{}, apiElement} - }) - - It("should successfully move the mouse to the middle of each selected element", func() { - Expect(selection.DoubleClick()).To(Succeed()) - Expect(session.MoveToCall.Element).To(Equal(apiElement)) - Expect(session.MoveToCall.Point).To(BeNil()) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.DoubleClick()).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when moving over any element fails", func() { - It("should retun an error", func() { - session.MoveToCall.Err = errors.New("some error") - Expect(selection.DoubleClick()).To(MatchError("failed to move mouse to 'CSS: #selector': some error")) - }) - }) - - It("should successfully double-click on each element", func() { - Expect(selection.DoubleClick()).To(Succeed()) - Expect(session.DoubleClickCall.Called).To(BeTrue()) - }) - - Context("when the double-clicking any element fails", func() { - It("should return an error", func() { - session.DoubleClickCall.Err = errors.New("some error") - Expect(selection.DoubleClick()).To(MatchError("failed to double-click on 'CSS: #selector': some error")) - }) - }) - }) - - Describe("#Fill", func() { - It("should successfully clear each element", func() { - Expect(selection.Fill("some text")).To(Succeed()) - Expect(firstElement.ClearCall.Called).To(BeTrue()) - Expect(secondElement.ClearCall.Called).To(BeTrue()) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.Fill("some text")).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when clearing any element fails", func() { - It("should return an error", func() { - secondElement.ClearCall.Err = errors.New("some error") - Expect(selection.Fill("some text")).To(MatchError("failed to clear 'CSS: #selector': some error")) - }) - }) - - It("should successfully fill each element with the provided text", func() { - Expect(selection.Fill("some text")).To(Succeed()) - Expect(firstElement.ValueCall.Text).To(Equal("some text")) - Expect(secondElement.ValueCall.Text).To(Equal("some text")) - }) - - Context("when entering text into any element fails", func() { - It("should return an error", func() { - secondElement.ValueCall.Err = errors.New("some error") - Expect(selection.Fill("some text")).To(MatchError("failed to enter text into 'CSS: #selector': some error")) - }) - }) - }) - - Describe("#Check", func() { - It("should successfully check the type of each checkbox", func() { - firstElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.GetAttributeCall.ReturnValue = "checkbox" - Expect(selection.Check()).To(Succeed()) - Expect(firstElement.GetAttributeCall.Attribute).To(Equal("type")) - Expect(secondElement.GetAttributeCall.Attribute).To(Equal("type")) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.Check()).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when any element fails to retrieve the 'type' attribute", func() { - It("should return an error", func() { - firstElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.GetAttributeCall.Err = errors.New("some error") - Expect(selection.Check()).To(MatchError("failed to retrieve type of 'CSS: #selector': some error")) - }) - }) - - Context("when any element is not a checkbox", func() { - It("should return an error", func() { - firstElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.GetAttributeCall.ReturnValue = "banana" - Expect(selection.Check()).To(MatchError("'CSS: #selector' does not refer to a checkbox")) - }) - }) - - Context("when all elements are checkboxes", func() { - BeforeEach(func() { - firstElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.GetAttributeCall.ReturnValue = "checkbox" - }) - - It("should not click on the checked checkbox successfully", func() { - firstElement.IsSelectedCall.ReturnSelected = true - Expect(selection.Check()).To(Succeed()) - Expect(firstElement.ClickCall.Called).To(BeFalse()) - }) - - It("should click on the unchecked checkboxes successfully", func() { - secondElement.IsSelectedCall.ReturnSelected = false - Expect(selection.Check()).To(Succeed()) - Expect(secondElement.ClickCall.Called).To(BeTrue()) - }) - - Context("when the determining the selected status of any element fails", func() { - It("should return an error", func() { - secondElement.IsSelectedCall.Err = errors.New("some error") - Expect(selection.Check()).To(MatchError("failed to retrieve state of 'CSS: #selector': some error")) - }) - }) - - Context("when clicking on the checkbox fails", func() { - It("should return an error", func() { - secondElement.ClickCall.Err = errors.New("some error") - Expect(selection.Check()).To(MatchError("failed to click on 'CSS: #selector': some error")) - }) - }) - }) - }) - - Describe("#Uncheck", func() { - It("should successfully click on a checked checkbox", func() { - firstElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.GetAttributeCall.ReturnValue = "checkbox" - secondElement.IsSelectedCall.ReturnSelected = true - Expect(selection.Uncheck()).To(Succeed()) - Expect(firstElement.ClickCall.Called).To(BeFalse()) - Expect(secondElement.ClickCall.Called).To(BeTrue()) - }) - }) - - Describe("#Select", func() { - var ( - firstOptionBuses []*mocks.Bus - secondOptionBuses []*mocks.Bus - firstOptions []*api.Element - secondOptions []*api.Element - ) - - BeforeEach(func() { - firstOptionBuses = []*mocks.Bus{&mocks.Bus{}, &mocks.Bus{}} - secondOptionBuses = []*mocks.Bus{&mocks.Bus{}, &mocks.Bus{}} - firstOptions = []*api.Element{ - &api.Element{ID: "one", Session: &api.Session{firstOptionBuses[0]}}, - &api.Element{ID: "two", Session: &api.Session{firstOptionBuses[1]}}, - } - secondOptions = []*api.Element{ - &api.Element{ID: "three", Session: &api.Session{secondOptionBuses[0]}}, - &api.Element{ID: "four", Session: &api.Session{secondOptionBuses[1]}}, - } - firstElement.GetElementsCall.ReturnElements = []*api.Element{firstOptions[0], firstOptions[1]} - secondElement.GetElementsCall.ReturnElements = []*api.Element{secondOptions[0], secondOptions[1]} - }) - - It("should successfully retrieve the options with matching text for each selected element", func() { - Expect(selection.Select("some text")).To(Succeed()) - Expect(firstElement.GetElementsCall.Selector.Using).To(Equal("xpath")) - Expect(firstElement.GetElementsCall.Selector.Value).To(Equal(`./option[normalize-space()="some text"]`)) - Expect(secondElement.GetElementsCall.Selector.Using).To(Equal("xpath")) - Expect(secondElement.GetElementsCall.Selector.Value).To(Equal(`./option[normalize-space()="some text"]`)) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.Select("some text")).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when we fail to retrieve any option", func() { - It("should return an error", func() { - secondElement.GetElementsCall.Err = errors.New("some error") - Expect(selection.Select("some text")).To(MatchError("failed to select specified option for some 'CSS: #selector': some error")) - }) - }) - - Context("when any of the elements has no options with matching text", func() { - It("should return an error", func() { - secondElement.GetElementsCall.ReturnElements = []*api.Element{} - Expect(selection.Select("some text")).To(MatchError(`no options with text "some text" found for some 'CSS: #selector'`)) - }) - }) - - It("should successfully click on all options with matching text", func() { - Expect(selection.Select("some text")).To(Succeed()) - Expect(firstOptionBuses[0].SendCall.Endpoint).To(Equal("element/one/click")) - Expect(firstOptionBuses[1].SendCall.Endpoint).To(Equal("element/two/click")) - Expect(secondOptionBuses[0].SendCall.Endpoint).To(Equal("element/three/click")) - Expect(secondOptionBuses[1].SendCall.Endpoint).To(Equal("element/four/click")) - }) - - Context("when the click fails for any of the options", func() { - It("should return an error", func() { - secondOptionBuses[1].SendCall.Err = errors.New("some error") - Expect(selection.Select("some text")).To(MatchError(`failed to click on option with text "some text" for some 'CSS: #selector': some error`)) - }) - }) - }) - - Describe("#Submit", func() { - It("should successfully submit all selected elements", func() { - Expect(selection.Submit()).To(Succeed()) - Expect(firstElement.SubmitCall.Called).To(BeTrue()) - Expect(secondElement.SubmitCall.Called).To(BeTrue()) - }) - - Context("when zero elements are returned", func() { - It("should return an error", func() { - elementRepository.GetAtLeastOneCall.Err = errors.New("some error") - Expect(selection.Submit()).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when any submit fails", func() { - It("should return an error", func() { - secondElement.SubmitCall.Err = errors.New("some error") - Expect(selection.Submit()).To(MatchError("failed to submit 'CSS: #selector': some error")) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository.go b/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository.go deleted file mode 100644 index ffa3923..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository.go +++ /dev/null @@ -1,133 +0,0 @@ -package selection - -import ( - "errors" - "fmt" - - "github.com/sclevine/agouti/api" -) - -type ElementRepository struct { - Client ElementClient -} - -type ElementClient interface { - GetElement(selector api.Selector) (*api.Element, error) - GetElements(selector api.Selector) ([]*api.Element, error) -} - -type Element interface { - ElementClient - GetText() (string, error) - GetAttribute(attribute string) (string, error) - GetCSS(property string) (string, error) - IsSelected() (bool, error) - IsDisplayed() (bool, error) - IsEnabled() (bool, error) - IsEqualTo(other *api.Element) (bool, error) - Click() error - Clear() error - Value(text string) error - Submit() error -} - -func (e *ElementRepository) GetAtLeastOne(selectors []Selector) ([]Element, error) { - elements, err := e.Get(selectors) - if err != nil { - return nil, err - } - - if len(elements) == 0 { - return nil, errors.New("no elements found") - } - - return elements, nil -} - -func (e *ElementRepository) GetExactlyOne(selectors []Selector) (Element, error) { - elements, err := e.GetAtLeastOne(selectors) - if err != nil { - return nil, err - } - - if len(elements) > 1 { - return nil, fmt.Errorf("method does not support multiple elements (%d)", len(elements)) - } - - return elements[0], nil -} - -func (e *ElementRepository) Get(selectors []Selector) ([]Element, error) { - if len(selectors) == 0 { - return nil, errors.New("empty selection") - } - - lastElements, err := retrieveElements(e.Client, selectors[0]) - if err != nil { - return nil, err - } - - for _, selector := range selectors[1:] { - elements := []Element{} - for _, element := range lastElements { - subElements, err := retrieveElements(element, selector) - if err != nil { - return nil, err - } - - elements = append(elements, subElements...) - } - lastElements = elements - } - return lastElements, nil -} - -func retrieveElements(client ElementClient, selector Selector) ([]Element, error) { - if selector.Single { - elements, err := client.GetElements(selector.API()) - if err != nil { - return nil, err - } - - if len(elements) == 0 { - return nil, errors.New("element not found") - } else if len(elements) > 1 { - return nil, errors.New("ambiguous find") - } - - return []Element{Element(elements[0])}, nil - } - - if selector.Indexed && selector.Index > 0 { - elements, err := client.GetElements(selector.API()) - if err != nil { - return nil, err - } - - if selector.Index >= len(elements) { - return nil, errors.New("element index out of range") - } - - return []Element{Element(elements[selector.Index])}, nil - } - - if selector.Indexed && selector.Index == 0 { - element, err := client.GetElement(selector.API()) - if err != nil { - return nil, err - } - return []Element{Element(element)}, nil - } - - elements, err := client.GetElements(selector.API()) - if err != nil { - return nil, err - } - - newElements := []Element{} - for _, element := range elements { - newElements = append(newElements, element) - } - - return newElements, nil -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository_test.go deleted file mode 100644 index 3a4c9dc..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/element_repository_test.go +++ /dev/null @@ -1,275 +0,0 @@ -package selection_test - -import ( - "errors" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/selection" -) - -var _ = Describe("ElementRepository", func() { - var ( - client *mocks.Session - repository *ElementRepository - ) - - BeforeEach(func() { - client = &mocks.Session{} - repository = &ElementRepository{Client: client} - }) - - Describe("#GetAtLeastOne", func() { - Context("when the client retrieves zero elements", func() { - It("should fail with an error", func() { - client.GetElementsCall.ReturnElements = []*api.Element{} - _, err := repository.GetAtLeastOne([]Selector{Selector{}}) - Expect(err).To(MatchError("no elements found")) - }) - }) - }) - - Describe("#GetExactlyOne", func() { - Context("when the client retrieves zero elements", func() { - It("should return an error", func() { - client.GetElementsCall.ReturnElements = []*api.Element{} - _, err := repository.GetExactlyOne([]Selector{Selector{}}) - Expect(err).To(MatchError("no elements found")) - }) - }) - - Context("when the client retrieves more than one element", func() { - It("should return an error", func() { - client.GetElementsCall.ReturnElements = []*api.Element{&api.Element{}, &api.Element{}} - _, err := repository.GetExactlyOne([]Selector{Selector{}}) - Expect(err).To(MatchError("method does not support multiple elements (2)")) - }) - }) - }) - - Describe("#Get", func() { - var ( - firstParentBus *mocks.Bus - firstParent *api.Element - secondParentBus *mocks.Bus - secondParent *api.Element - children []Element - parentSelector Selector - parentSelectorJSON string - childSelector Selector - childSelectorJSON string - ) - - BeforeEach(func() { - firstParentBus = &mocks.Bus{} - firstParent = &api.Element{Session: &api.Session{firstParentBus}} - secondParentBus = &mocks.Bus{} - secondParent = &api.Element{Session: &api.Session{secondParentBus}} - children = []Element{ - Element(&api.Element{ID: "first child", Session: &api.Session{firstParentBus}}), - Element(&api.Element{ID: "second child", Session: &api.Session{firstParentBus}}), - Element(&api.Element{ID: "third child", Session: &api.Session{secondParentBus}}), - Element(&api.Element{ID: "fourth child", Session: &api.Session{secondParentBus}}), - } - firstParentBus.SendCall.Result = `[{"ELEMENT": "first child"}, {"ELEMENT": "second child"}]` - secondParentBus.SendCall.Result = `[{"ELEMENT": "third child"}, {"ELEMENT": "fourth child"}]` - client.GetElementsCall.ReturnElements = []*api.Element{firstParent, secondParent} - parentSelector = Selector{Type: "css selector", Value: "parents"} - parentSelectorJSON = `{"using": "css selector", "value": "parents"}` - childSelector = Selector{Type: "xpath", Value: "children"} - childSelectorJSON = `{"using": "xpath", "value": "children"}` - }) - - Context("when all elements are successfully retrieved", func() { - It("should retrieve the parent elements using the client", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(client.GetElementsCall.Selector).To(Equal(parentSelector.API())) - }) - - It("should retrieve the child elements of the parent selector", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(firstParentBus.SendCall.BodyJSON).To(MatchJSON(childSelectorJSON)) - Expect(secondParentBus.SendCall.BodyJSON).To(MatchJSON(childSelectorJSON)) - }) - - It("should successfully return all of the children", func() { - Expect(repository.Get([]Selector{parentSelector, childSelector})).To(Equal(children)) - }) - }) - - Context("when all non-zero-indexed elements are successfully retrieved", func() { - BeforeEach(func() { - parentSelector.Index = 1 - parentSelector.Indexed = true - childSelector.Index = 1 - childSelector.Indexed = true - }) - - It("should retrieve the parent elements using the client", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(client.GetElementsCall.Selector).To(Equal(parentSelector.API())) - }) - - It("should retrieve the child elements of the second parent selector", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(firstParentBus.SendCall.BodyJSON).To(BeEmpty()) - Expect(secondParentBus.SendCall.BodyJSON).To(MatchJSON(childSelectorJSON)) - }) - - It("should return only the selected child elements", func() { - Expect(repository.Get([]Selector{parentSelector, childSelector})).To(Equal([]Element{children[3]})) - }) - }) - - Context("when all zero-indexed elements are successfully retrieved", func() { - BeforeEach(func() { - firstParentBus.SendCall.Result = `{"ELEMENT": "first child"}` - client.GetElementCall.ReturnElement = firstParent - parentSelector.Index = 0 - parentSelector.Indexed = true - childSelector.Index = 0 - childSelector.Indexed = true - }) - - It("should retrieve the first parent element using the client", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(client.GetElementCall.Selector).To(Equal(parentSelector.API())) - }) - - It("should retrieve the first child element of the parent selector", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(firstParentBus.SendCall.BodyJSON).To(MatchJSON(childSelectorJSON)) - }) - - It("should return only the selected child element", func() { - Expect(repository.Get([]Selector{parentSelector, childSelector})).To(Equal([]Element{children[0]})) - }) - }) - - Context("when single-element-only elements are successfully retrieved", func() { - BeforeEach(func() { - firstParentBus.SendCall.Result = `[{"ELEMENT": "first child"}]` - client.GetElementsCall.ReturnElements = []*api.Element{firstParent} - parentSelector.Single = true - childSelector.Single = true - }) - - It("should retrieve the parent element using the client", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(client.GetElementsCall.Selector).To(Equal(parentSelector.API())) - }) - - It("should retrieve the child element of the parent selector", func() { - repository.Get([]Selector{parentSelector, childSelector}) - Expect(firstParentBus.SendCall.BodyJSON).To(MatchJSON(childSelectorJSON)) - }) - - It("should return only the selected child element", func() { - Expect(repository.Get([]Selector{parentSelector, childSelector})).To(Equal([]Element{children[0]})) - }) - }) - - Context("when there is no selection", func() { - It("should return an error", func() { - _, err := repository.Get([]Selector{}) - Expect(err).To(MatchError("empty selection")) - }) - }) - - Context("when retrieving the parent elements fails", func() { - It("should return an error", func() { - client.GetElementsCall.Err = errors.New("some error") - _, err := repository.Get([]Selector{parentSelector}) - Expect(err).To(MatchError("some error")) - }) - }) - - Context("when retrieving any of the child elements fails", func() { - It("should return an error", func() { - secondParentBus.SendCall.Err = errors.New("some error") - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("some error")) - }) - }) - - Context("when a single-element-only parent selection refers to multiple parents", func() { - It("should return an error", func() { - parentSelector.Single = true - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("ambiguous find")) - }) - }) - - Context("when a single-element-only parent selection refers to no parents", func() { - It("should return an error", func() { - parentSelector.Single = true - client.GetElementsCall.ReturnElements = []*api.Element{} - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("element not found")) - }) - }) - - Context("when any single-element-only child selection refers to multiple child elements", func() { - It("should return an error", func() { - childSelector.Single = true - firstParentBus.SendCall.Result = `[{"ELEMENT": "first child"}]` - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("ambiguous find")) - }) - }) - - Context("when any single-element-only child selection refers to no child elements", func() { - It("should return an error", func() { - childSelector.Single = true - firstParentBus.SendCall.Result = `[]` - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("element not found")) - }) - }) - - Context("when the parent selection index is out of range", func() { - It("should return an error", func() { - parentSelector.Index = 2 - parentSelector.Indexed = true - _, err := repository.Get([]Selector{parentSelector}) - Expect(err).To(MatchError("element index out of range")) - }) - }) - - Context("when child selection indices are out of range", func() { - It("should return an error", func() { - parentSelector.Index = 1 - parentSelector.Indexed = true - childSelector.Index = 2 - childSelector.Indexed = true - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("element index out of range")) - }) - }) - - Context("when a zero-indexed parent selection element does not exist", func() { - It("should return an error", func() { - client.GetElementCall.Err = errors.New("some error") - parentSelector.Index = 0 - parentSelector.Indexed = true - _, err := repository.Get([]Selector{parentSelector}) - Expect(err).To(MatchError("some error")) - }) - }) - - Context("when a zero-indexed child selection element does not exist", func() { - It("should return an error", func() { - firstParentBus.SendCall.Err = errors.New("some error") - client.GetElementCall.ReturnElement = firstParent - parentSelector.Index = 0 - parentSelector.Indexed = true - childSelector.Index = 0 - childSelector.Indexed = true - _, err := repository.Get([]Selector{parentSelector, childSelector}) - Expect(err).To(MatchError("some error")) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/properties.go b/vendor/github.com/sclevine/agouti/core/internal/selection/properties.go deleted file mode 100644 index 87db6bf..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/properties.go +++ /dev/null @@ -1,91 +0,0 @@ -package selection - -import "fmt" - -func (s *Selection) Text() (string, error) { - element, err := s.Elements.GetExactlyOne(s.selectors) - if err != nil { - return "", fmt.Errorf("failed to select '%s': %s", s, err) - } - - text, err := element.GetText() - if err != nil { - return "", fmt.Errorf("failed to retrieve text for '%s': %s", s, err) - } - return text, nil -} - -func (s *Selection) Active() (bool, error) { - element, err := s.Elements.GetExactlyOne(s.selectors) - if err != nil { - return false, fmt.Errorf("failed to select '%s': %s", s, err) - } - - activeElement, err := s.Session.GetActiveElement() - if err != nil { - return false, fmt.Errorf("failed to retrieve active element: %s", err) - } - - equal, err := element.IsEqualTo(activeElement) - if err != nil { - return false, fmt.Errorf("failed to compare selection to active element: %s", err) - } - - return equal, nil -} - -type propertyMethod func(element Element, property string) (string, error) - -func (s *Selection) hasProperty(method propertyMethod, property, name string) (string, error) { - element, err := s.Elements.GetExactlyOne(s.selectors) - if err != nil { - return "", fmt.Errorf("failed to select '%s': %s", s, err) - } - - value, err := method(element, property) - if err != nil { - return "", fmt.Errorf("failed to retrieve %s value for '%s': %s", name, s, err) - } - return value, nil -} - -func (s *Selection) Attribute(attribute string) (string, error) { - return s.hasProperty(Element.GetAttribute, attribute, "attribute") -} - -func (s *Selection) CSS(property string) (string, error) { - return s.hasProperty(Element.GetCSS, property, "CSS property") -} - -type stateMethod func(element Element) (bool, error) - -func (s *Selection) hasState(method stateMethod, name string) (bool, error) { - elements, err := s.Elements.GetAtLeastOne(s.selectors) - if err != nil { - return false, fmt.Errorf("failed to select '%s': %s", s, err) - } - - for _, element := range elements { - pass, err := method(element) - if err != nil { - return false, fmt.Errorf("failed to determine whether some '%s' is %s: %s", s, name, err) - } - if !pass { - return false, nil - } - } - - return true, nil -} - -func (s *Selection) Selected() (bool, error) { - return s.hasState(Element.IsSelected, "selected") -} - -func (s *Selection) Visible() (bool, error) { - return s.hasState(Element.IsDisplayed, "visible") -} - -func (s *Selection) Enabled() (bool, error) { - return s.hasState(Element.IsEnabled, "enabled") -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/properties_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/properties_test.go deleted file mode 100644 index 25fd968..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/properties_test.go +++ /dev/null @@ -1,233 +0,0 @@ -package selection_test - -import ( - "errors" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/selection" -) - -var _ = Describe("Selection", func() { - var ( - selection *Selection - session *mocks.Session - elementRepository *mocks.ElementRepository - element *mocks.Element - secondElement *mocks.Element - ) - - BeforeEach(func() { - session = &mocks.Session{} - element = &mocks.Element{} - secondElement = &mocks.Element{} - elementRepository = &mocks.ElementRepository{} - emptySelection := &Selection{Session: session, Elements: elementRepository} - selection = emptySelection.AppendCSS("#selector") - }) - - Describe("#Text", func() { - BeforeEach(func() { - elementRepository.GetExactlyOneCall.ReturnElement = element - }) - - Context("when the session fails to retrieve the element text", func() { - It("should return an error", func() { - element.GetTextCall.Err = errors.New("some error") - _, err := selection.Text() - Expect(err).To(MatchError("failed to retrieve text for 'CSS: #selector': some error")) - }) - }) - - Context("when the session succeeds in retrieving the element text", func() { - It("should successfully return the text", func() { - element.GetTextCall.ReturnText = "some text" - Expect(selection.Text()).To(Equal("some text")) - }) - }) - }) - - Describe("#Active", func() { - BeforeEach(func() { - elementRepository.GetExactlyOneCall.ReturnElement = element - }) - - Context("when the session fails to retrieve the active element", func() { - It("should return an error", func() { - session.GetActiveElementCall.Err = errors.New("some error") - _, err := selection.Active() - Expect(err).To(MatchError("failed to retrieve active element: some error")) - }) - }) - - It("should compare the active and selected elements", func() { - activeElement := &api.Element{} - session.GetActiveElementCall.ReturnElement = activeElement - selection.Active() - Expect(element.IsEqualToCall.Element).To(Equal(activeElement)) - }) - - Context("when the session fails to compare active element to the selected element", func() { - It("should return an error", func() { - element.IsEqualToCall.Err = errors.New("some error") - _, err := selection.Active() - Expect(err).To(MatchError("failed to compare selection to active element: some error")) - }) - }) - - Context("when the active element equals the selected element", func() { - It("should successfully return true", func() { - element.IsEqualToCall.ReturnEquals = true - Expect(selection.Active()).To(BeTrue()) - }) - }) - - Context("when the active element does not equal the selected element", func() { - It("should successfully return false", func() { - element.IsEqualToCall.ReturnEquals = false - Expect(selection.Active()).To(BeFalse()) - }) - }) - }) - - Describe("#Attribute", func() { - BeforeEach(func() { - elementRepository.GetExactlyOneCall.ReturnElement = element - }) - - It("should request the attribute value using the attribute name", func() { - selection.Attribute("some-attribute") - Expect(element.GetAttributeCall.Attribute).To(Equal("some-attribute")) - }) - - Context("when the session fails to retrieve the requested element attribute", func() { - It("should return an error", func() { - element.GetAttributeCall.Err = errors.New("some error") - _, err := selection.Attribute("some-attribute") - Expect(err).To(MatchError("failed to retrieve attribute value for 'CSS: #selector': some error")) - }) - }) - - Context("when the session succeeds in retrieving the requested element attribute", func() { - It("should successfully return the attribute value", func() { - element.GetAttributeCall.ReturnValue = "some value" - Expect(selection.Attribute("some-attribute")).To(Equal("some value")) - }) - }) - }) - - Describe("#CSS", func() { - BeforeEach(func() { - elementRepository.GetExactlyOneCall.ReturnElement = element - }) - - It("should successfully request the CSS property value using the property name", func() { - selection.CSS("some-property") - Expect(element.GetCSSCall.Property).To(Equal("some-property")) - }) - - Context("when the the session fails to retrieve the requested element CSS property", func() { - It("should return an error", func() { - element.GetCSSCall.Err = errors.New("some error") - _, err := selection.CSS("some-property") - Expect(err).To(MatchError("failed to retrieve CSS property value for 'CSS: #selector': some error")) - }) - }) - - Context("when the session succeeds in retrieving the requested element CSS property", func() { - It("should successfully return the property value", func() { - element.GetCSSCall.ReturnValue = "some value" - Expect(selection.CSS("some-property")).To(Equal("some value")) - }) - }) - }) - - Describe("#Selected", func() { - BeforeEach(func() { - elementRepository.GetAtLeastOneCall.ReturnElements = []Element{element, secondElement} - }) - - Context("when the the session fails to retrieve any elements' selected status", func() { - It("should return an error", func() { - element.IsSelectedCall.ReturnSelected = true - secondElement.IsSelectedCall.Err = errors.New("some error") - _, err := selection.Selected() - Expect(err).To(MatchError("failed to determine whether some 'CSS: #selector' is selected: some error")) - }) - }) - - Context("when the session succeeds in retrieving all elements' selected status", func() { - It("should return true when all elements are selected", func() { - element.IsSelectedCall.ReturnSelected = true - secondElement.IsSelectedCall.ReturnSelected = true - Expect(selection.Selected()).To(BeTrue()) - }) - - It("should return false when any elements are not selected", func() { - element.IsSelectedCall.ReturnSelected = true - secondElement.IsSelectedCall.ReturnSelected = false - Expect(selection.Selected()).To(BeFalse()) - }) - }) - }) - - Describe("#Visible", func() { - BeforeEach(func() { - elementRepository.GetAtLeastOneCall.ReturnElements = []Element{element, secondElement} - }) - - Context("when the the session fails to retrieve any elements' visible status", func() { - It("should return an error", func() { - element.IsDisplayedCall.ReturnDisplayed = true - secondElement.IsDisplayedCall.Err = errors.New("some error") - _, err := selection.Visible() - Expect(err).To(MatchError("failed to determine whether some 'CSS: #selector' is visible: some error")) - }) - }) - - Context("when the session succeeds in retrieving all elements' visible status", func() { - It("should return true when all elements are visible", func() { - element.IsDisplayedCall.ReturnDisplayed = true - secondElement.IsDisplayedCall.ReturnDisplayed = true - Expect(selection.Visible()).To(BeTrue()) - }) - - It("should return false when any elements are not visible", func() { - element.IsDisplayedCall.ReturnDisplayed = true - secondElement.IsDisplayedCall.ReturnDisplayed = false - Expect(selection.Visible()).To(BeFalse()) - }) - }) - }) - - Describe("#Enabled", func() { - BeforeEach(func() { - elementRepository.GetAtLeastOneCall.ReturnElements = []Element{element, secondElement} - }) - - Context("when the the session fails to retrieve any elements' enabled status", func() { - It("should return an error", func() { - element.IsEnabledCall.ReturnEnabled = true - secondElement.IsEnabledCall.Err = errors.New("some error") - _, err := selection.Enabled() - Expect(err).To(MatchError("failed to determine whether some 'CSS: #selector' is enabled: some error")) - }) - }) - - Context("when the session succeeds in retrieving all elements' enabled status", func() { - It("should return true when all elements are enabled", func() { - element.IsEnabledCall.ReturnEnabled = true - secondElement.IsEnabledCall.ReturnEnabled = true - Expect(selection.Enabled()).To(BeTrue()) - }) - - It("should return false when any elements are not enabled", func() { - element.IsEnabledCall.ReturnEnabled = true - secondElement.IsEnabledCall.ReturnEnabled = false - Expect(selection.Enabled()).To(BeFalse()) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/selection.go b/vendor/github.com/sclevine/agouti/core/internal/selection/selection.go deleted file mode 100644 index 3f84d35..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/selection.go +++ /dev/null @@ -1,94 +0,0 @@ -package selection - -import ( - "fmt" - - "github.com/sclevine/agouti/api" -) - -type Selection struct { - Session interface { - GetActiveElement() (*api.Element, error) - DoubleClick() error - MoveTo(element *api.Element, point api.Offset) error - Frame(frame *api.Element) error - } - Elements interface { - Get(selectors []Selector) ([]Element, error) - GetAtLeastOne(selectors []Selector) ([]Element, error) - GetExactlyOne(selectors []Selector) (Element, error) - } - selectors []Selector -} - -func NewSelection(session *api.Session) *Selection { - return &Selection{session, &ElementRepository{session}, nil} -} - -func (s *Selection) AppendCSS(cssSelector string) *Selection { - selector := Selector{Type: "css selector", Value: cssSelector} - - if s.canMergeCSS() { - lastIndex := len(s.selectors) - 1 - selector.Value = s.selectors[lastIndex].Value + " " + selector.Value - return &Selection{s.Session, s.Elements, appendSelector(s.selectors[:lastIndex], selector)} - } - - return &Selection{s.Session, s.Elements, appendSelector(s.selectors, selector)} -} - -func (s *Selection) canMergeCSS() bool { - if len(s.selectors) == 0 { - return false - } - last := s.selectors[len(s.selectors)-1] - return last.Type == "css selector" && !last.Indexed && !last.Single -} - -func (s *Selection) AppendXPath(xPathSelector string) *Selection { - selector := Selector{Type: "xpath", Value: xPathSelector} - return &Selection{s.Session, s.Elements, appendSelector(s.selectors, selector)} -} - -func (s *Selection) AppendLink(text string) *Selection { - selector := Selector{Type: "link text", Value: text} - return &Selection{s.Session, s.Elements, appendSelector(s.selectors, selector)} -} - -func (s *Selection) AppendLabeled(text string) *Selection { - return s.AppendXPath(fmt.Sprintf(`//input[@id=(//label[normalize-space()="%s"]/@for)] | //label[normalize-space()="%s"]/input`, text, text)) -} - -func (s *Selection) AppendButton(text string) *Selection { - return s.AppendXPath(fmt.Sprintf(`//input[@type="submit" or @type="button"][normalize-space(@value)="%s"] | //button[normalize-space()="%s"]`, text, text)) -} - -func (s *Selection) Single() *Selection { - lastIndex := len(s.selectors) - 1 - if lastIndex < 0 { - return &Selection{s.Session, s.Elements, nil} - } - - selector := s.selectors[lastIndex] - selector.Single = true - selector.Indexed = false - return &Selection{s.Session, s.Elements, appendSelector(s.selectors[:lastIndex], selector)} -} - -func (s *Selection) At(index int) *Selection { - lastIndex := len(s.selectors) - 1 - if lastIndex < 0 { - return &Selection{s.Session, s.Elements, nil} - } - - selector := s.selectors[lastIndex] - selector.Single = false - selector.Indexed = true - selector.Index = index - return &Selection{s.Session, s.Elements, appendSelector(s.selectors[:lastIndex], selector)} -} - -func appendSelector(selectors []Selector, selector Selector) []Selector { - selectorsCopy := append([]Selector(nil), selectors...) - return append(selectorsCopy, selector) -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/selection_suite_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/selection_suite_test.go deleted file mode 100644 index 82253a1..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/selection_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package selection_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestSelection(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Selection Suite") -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/selection_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/selection_test.go deleted file mode 100644 index a4b51e2..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/selection_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package selection_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/selection" -) - -var _ = Describe("Selection", func() { - var ( - selection *Selection - session *mocks.Session - elementRepository *mocks.ElementRepository - ) - - BeforeEach(func() { - session = &mocks.Session{} - elementRepository = &mocks.ElementRepository{} - selection = &Selection{Session: session, Elements: elementRepository} - }) - - Describe(".NewSelection", func() { - It("should return an empty selection with the provided session and element repository", func() { - realSession := &api.Session{} - selection = NewSelection(realSession) - Expect(selection.Session).To(Equal(realSession)) - Expect(selection.Elements.(*ElementRepository).Client).To(Equal(realSession)) - }) - }) - - Describe("#AppendCSS", func() { - Context("when the selection ends with an unindexed CSS selector", func() { - It("should modify the last CSS selector to include the new selector", func() { - Expect(selection.AppendCSS("#selector").AppendCSS("#subselector").String()).To(Equal("CSS: #selector #subselector")) - }) - - It("should propagate the session and element repository", func() { - Expect(selection.AppendCSS("#selector").AppendCSS("#subselector").Session).To(Equal(selection.Session)) - Expect(selection.AppendCSS("#selector").AppendCSS("#subselector").Elements).To(Equal(selection.Elements)) - }) - }) - - It("should propagate the session and element repository in all other cases", func() { - Expect(selection.AppendCSS("#selector").Session).To(Equal(selection.Session)) - Expect(selection.AppendCSS("#selector").Elements).To(Equal(selection.Elements)) - }) - - Context("when there is no selection", func() { - It("should add a new CSS selector to the selection", func() { - Expect(selection.AppendCSS("#selector").String()).To(Equal("CSS: #selector")) - }) - }) - - Context("when the selection ends with an non-CSS selector", func() { - It("should add a new selector to the selection", func() { - xpath := selection.AppendXPath("//selector") - Expect(xpath.AppendCSS("#subselector").String()).To(Equal("XPath: //selector | CSS: #subselector")) - }) - }) - - Context("when the selection ends with an indexed selector", func() { - It("should add a new selector to the selection", func() { - Expect(selection.AppendCSS("#selector").At(0).AppendCSS("#subselector").String()).To(Equal("CSS: #selector [0] | CSS: #subselector")) - }) - }) - - Context("when the selection ends with a single-element-only selector", func() { - It("should add a new selector to the selection", func() { - Expect(selection.AppendCSS("#selector").Single().AppendCSS("#subselector").String()).To(Equal("CSS: #selector [single] | CSS: #subselector")) - }) - }) - }) - - Describe("#AppendXPath", func() { - It("should propagate the session and element repository", func() { - Expect(selection.AppendXPath("//selector").Session).To(Equal(selection.Session)) - Expect(selection.AppendXPath("//selector").Elements).To(Equal(selection.Elements)) - }) - - It("should add a new XPath selector to the selection", func() { - Expect(selection.AppendXPath("//selector").String()).To(Equal("XPath: //selector")) - }) - }) - - Describe("#AppendLink", func() { - It("should propagate the session and element repository", func() { - Expect(selection.AppendLink("some text").Session).To(Equal(selection.Session)) - Expect(selection.AppendLink("some text").Elements).To(Equal(selection.Elements)) - }) - - It("should add a new 'link text' selector to the selection", func() { - Expect(selection.AppendLink("some text").String()).To(Equal(`Link: "some text"`)) - }) - }) - - Describe("#AppendLabeled", func() { - It("should propagate the session and element repository", func() { - Expect(selection.AppendLabeled("some text").Session).To(Equal(selection.Session)) - Expect(selection.AppendLabeled("some text").Elements).To(Equal(selection.Elements)) - }) - - It("should add a new XPath label-lookup selector to the selection", func() { - Expect(selection.AppendLabeled("some text").String()).To(Equal(`XPath: //input[@id=(//label[normalize-space()="some text"]/@for)] | //label[normalize-space()="some text"]/input`)) - }) - }) - - Describe("#AppendButton", func() { - It("should propagate the session and element repository", func() { - Expect(selection.AppendButton("some text").Session).To(Equal(selection.Session)) - Expect(selection.AppendButton("some text").Elements).To(Equal(selection.Elements)) - }) - - It("should add a new XPath label-lookup selector to the selection", func() { - Expect(selection.AppendButton("some text").String()).To(Equal(`XPath: //input[@type="submit" or @type="button"][normalize-space(@value)="some text"] | //button[normalize-space()="some text"]`)) - }) - }) - - Describe("#At", func() { - Context("when called on a selection with no selectors", func() { - It("should return an empty selection", func() { - Expect(selection.At(1).String()).To(Equal("")) - }) - - It("should propagate the session and element repository", func() { - Expect(selection.At(0).Session).To(Equal(selection.Session)) - Expect(selection.At(0).Elements).To(Equal(selection.Elements)) - }) - }) - - Context("when called on a selection with selectors", func() { - It("should select an index of the current selection", func() { - Expect(selection.AppendCSS("#selector").At(1).String()).To(Equal("CSS: #selector [1]")) - }) - - It("should propagate the session and element repository", func() { - Expect(selection.AppendCSS("#selector").At(0).Session).To(Equal(selection.Session)) - Expect(selection.AppendCSS("#selector").At(0).Elements).To(Equal(selection.Elements)) - }) - }) - }) - - Describe("#Single", func() { - Context("when called on a selection with no selectors", func() { - It("should return an empty selection", func() { - Expect(selection.Single().String()).To(Equal("")) - }) - - It("should propagate the session and element repository", func() { - Expect(selection.Single().Session).To(Equal(selection.Session)) - Expect(selection.Single().Elements).To(Equal(selection.Elements)) - }) - }) - - Context("when called on a selection with selectors", func() { - It("should select a single element of the current selection", func() { - Expect(selection.AppendCSS("#selector").Single().String()).To(Equal("CSS: #selector [single]")) - }) - - It("should propagate the session and element repository", func() { - Expect(selection.AppendCSS("#selector").Single().Session).To(Equal(selection.Session)) - Expect(selection.AppendCSS("#selector").Single().Elements).To(Equal(selection.Elements)) - }) - }) - }) - - Describe("selectors are always copied", func() { - Context("when two CSS selections are created from the same XPath parent", func() { - It("should not overwrite the first created child", func() { - parent := selection.AppendXPath("//one").AppendXPath("//two").AppendXPath("//parent") - firstChild := parent.AppendCSS("#firstChild") - parent.AppendCSS("#secondChild") - Expect(firstChild.String()).To(Equal("XPath: //one | XPath: //two | XPath: //parent | CSS: #firstChild")) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/selector.go b/vendor/github.com/sclevine/agouti/core/internal/selection/selector.go deleted file mode 100644 index 45f3620..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/selector.go +++ /dev/null @@ -1,40 +0,0 @@ -package selection - -import ( - "fmt" - - "github.com/sclevine/agouti/api" -) - -type Selector struct { - Type string - Value string - Index int - Indexed bool - Single bool -} - -func (s Selector) String() string { - var suffix string - - if s.Single { - suffix = " [single]" - } else if s.Indexed { - suffix = fmt.Sprintf(" [%d]", s.Index) - } - - switch s.Type { - case "css selector": - return fmt.Sprintf("CSS: %s%s", s.Value, suffix) - case "xpath": - return fmt.Sprintf("XPath: %s%s", s.Value, suffix) - case "link text": - return fmt.Sprintf(`Link: "%s"%s`, s.Value, suffix) - default: - return "Invalid selector" - } -} - -func (s Selector) API() api.Selector { - return api.Selector{Using: s.Type, Value: s.Value} -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/utils.go b/vendor/github.com/sclevine/agouti/core/internal/selection/utils.go deleted file mode 100644 index b0373ab..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/utils.go +++ /dev/null @@ -1,58 +0,0 @@ -package selection - -import ( - "fmt" - "strings" - - "github.com/sclevine/agouti/api" -) - -func (s *Selection) String() string { - var tags []string - - for _, selector := range s.selectors { - tags = append(tags, selector.String()) - } - - return strings.Join(tags, " | ") -} - -func (s *Selection) Count() (int, error) { - elements, err := s.Elements.Get(s.selectors) - if err != nil { - return 0, fmt.Errorf("failed to select '%s': %s", s, err) - } - - return len(elements), nil -} - -func (s *Selection) EqualsElement(other *Selection) (bool, error) { - element, err := s.Elements.GetExactlyOne(s.selectors) - if err != nil { - return false, fmt.Errorf("failed to select '%s': %s", s, err) - } - - otherElement, err := other.Elements.GetExactlyOne(s.selectors) - if err != nil { - return false, fmt.Errorf("failed to select '%s': %s", other, err) - } - - equal, err := element.IsEqualTo(otherElement.(*api.Element)) - if err != nil { - return false, fmt.Errorf("failed to compare '%s' to '%s': %s", s, other, err) - } - - return equal, nil -} - -func (s *Selection) SwitchToFrame() error { - element, err := s.Elements.GetExactlyOne(s.selectors) - if err != nil { - return fmt.Errorf("failed to select '%s': %s", s, err) - } - - if err := s.Session.Frame(element.(*api.Element)); err != nil { - return fmt.Errorf("failed to switch to frame '%s': %s", s, err) - } - return nil -} diff --git a/vendor/github.com/sclevine/agouti/core/internal/selection/utils_test.go b/vendor/github.com/sclevine/agouti/core/internal/selection/utils_test.go deleted file mode 100644 index e93159f..0000000 --- a/vendor/github.com/sclevine/agouti/core/internal/selection/utils_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package selection_test - -import ( - "errors" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/mocks" - . "github.com/sclevine/agouti/core/internal/selection" -) - -var _ = Describe("Utils", func() { - var ( - selection *Selection - session *mocks.Session - elementRepository *mocks.ElementRepository - element *mocks.Element - ) - - BeforeEach(func() { - session = &mocks.Session{} - elementRepository = &mocks.ElementRepository{} - emptySelection := &Selection{Session: session, Elements: elementRepository} - selection = emptySelection.AppendCSS("#selector") - element = &mocks.Element{} - }) - - Describe("#Count", func() { - BeforeEach(func() { - elementRepository.GetCall.ReturnElements = []Element{element, element} - }) - - It("should request elements from the session using the provided selector", func() { - selection.Count() - Expect(elementRepository.GetCall.Selectors).To(Equal([]Selector{Selector{Type: "css selector", Value: "#selector"}})) - }) - - Context("when the session succeeds in retrieving the elements", func() { - It("should successfully return the text", func() { - Expect(selection.Count()).To(Equal(2)) - }) - }) - - Context("when the the session fails to retrieve the elements", func() { - It("should return an error", func() { - elementRepository.GetCall.Err = errors.New("some error") - _, err := selection.Count() - Expect(err).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - }) - - Describe("#EqualsElement", func() { - var ( - otherElementRepository *mocks.ElementRepository - otherSelection *Selection - otherElement *api.Element - ) - - BeforeEach(func() { - elementRepository.GetExactlyOneCall.ReturnElement = element - otherElementRepository = &mocks.ElementRepository{} - emptySelection := &Selection{Elements: otherElementRepository} - otherSelection = emptySelection.AppendCSS("#other_selector") - otherElement = &api.Element{} - otherElementRepository.GetExactlyOneCall.ReturnElement = otherElement - }) - - It("should compare the selection elements for equality", func() { - selection.EqualsElement(otherSelection) - Expect(element.IsEqualToCall.Element).To(Equal(otherElement)) - }) - - It("should successfully return true if they are equal", func() { - element.IsEqualToCall.ReturnEquals = true - Expect(selection.EqualsElement(otherSelection)).To(BeTrue()) - }) - - It("should successfully return false if they are not equal", func() { - element.IsEqualToCall.ReturnEquals = false - Expect(selection.EqualsElement(otherSelection)).To(BeFalse()) - }) - - Context("when there is an error retrieving elements from the selection", func() { - It("should return an error", func() { - elementRepository.GetExactlyOneCall.Err = errors.New("some error") - _, err := selection.EqualsElement(otherSelection) - Expect(err).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when there is an error retrieving elements from the other selection", func() { - It("should return an error", func() { - otherElementRepository.GetExactlyOneCall.Err = errors.New("some error") - _, err := selection.EqualsElement(otherSelection) - Expect(err).To(MatchError("failed to select 'CSS: #other_selector': some error")) - }) - }) - - Context("when the session fails to compare the elements", func() { - It("should return an error", func() { - element.IsEqualToCall.Err = errors.New("some error") - _, err := selection.EqualsElement(otherSelection) - Expect(err).To(MatchError("failed to compare 'CSS: #selector' to 'CSS: #other_selector': some error")) - }) - }) - }) - - Describe("#SwitchToFrame", func() { - var apiElement *api.Element - - BeforeEach(func() { - apiElement = &api.Element{} - elementRepository.GetExactlyOneCall.ReturnElement = apiElement - }) - - It("should successfully switch to the frame indicated by the selection", func() { - Expect(selection.SwitchToFrame()).To(Succeed()) - Expect(session.FrameCall.Frame).To(Equal(apiElement)) - }) - - Context("when there is an error retrieving exactly one element", func() { - It("should return an error", func() { - elementRepository.GetExactlyOneCall.Err = errors.New("some error") - err := selection.SwitchToFrame() - Expect(err).To(MatchError("failed to select 'CSS: #selector': some error")) - }) - }) - - Context("when the session fails to switch frames", func() { - It("should return an error", func() { - session.FrameCall.Err = errors.New("some error") - err := selection.SwitchToFrame() - Expect(err).To(MatchError("failed to switch to frame 'CSS: #selector': some error")) - }) - }) - }) -}) diff --git a/vendor/github.com/sclevine/agouti/core/page.go b/vendor/github.com/sclevine/agouti/core/page.go deleted file mode 100644 index 135e54d..0000000 --- a/vendor/github.com/sclevine/agouti/core/page.go +++ /dev/null @@ -1,135 +0,0 @@ -package core - -import ( - "time" - - "github.com/sclevine/agouti" - "github.com/sclevine/agouti/api" - "github.com/sclevine/agouti/core/internal/page" - "github.com/sclevine/agouti/core/internal/selection" -) - -// A Page represents an open browser session. Pages may be created using the -// WebDriver#Page() method or by calling the Connect or SauceLabs functions. -type Page interface { - // Selections are created using the Selectable page methods (ex. Find()). - Selectable - - // Destroy closes the session and any open browsers processes. - Destroy() error - - // Navigate navigates to the provided URL. - Navigate(url string) error - - // SetCookie sets a cookie on the page. - SetCookie(cookie agouti.Cookie) error - - // DeleteCookie deletes a cookie on the page by name. - DeleteCookie(name string) error - - // ClearCookies deletes all cookies on the page. - ClearCookies() error - - // URL returns the current page URL. - URL() (string, error) - - // Size sets the current page size in pixels. - Size(width, height int) error - - // Screenshot takes a screenshot and saves it to the provided filename. - Screenshot(filename string) error - - // Title returns the page title. - Title() (string, error) - - // HTML returns the current contents of the DOM for the entire page. - HTML() (string, error) - - // RunScript runs the JavaScript provided in the body. Any keys present in - // the arguments map will be available as variables in the body. - // Values provided in arguments are converted into javascript objects. - // If the body returns a value, it will be unmarshalled into the result argument. - // Simple example: - // var number int - // page.RunScript("return test;", map[string]interface{}{"test": 100}, &number) - // fmt.Println(number) - // -> 100 - RunScript(body string, arguments map[string]interface{}, result interface{}) error - - // PopupText returns the current alert, confirm, or prompt popup text. - PopupText() (string, error) - - // EnterPopupText enters text into an open prompt popup. - EnterPopupText(text string) error - - // ConfirmPopup confirms an alert, confirm, or prompt popup. - ConfirmPopup() error - - // CancelPopup cancels an alert, confirm, or prompt popup. - CancelPopup() error - - // Forward navigates forward in history. - Forward() error - - // Back navigates backwards in history. - Back() error - - // Refresh refreshes the page. - Refresh() error - - // SwitchToParentFrame focuses on the immediate parent frame of a frame selected - // by Selection#Frame. After switching, all new and existing selections will refer - // to the parent frame. All further Page methods will apply to this frame as well. - // - // This method is not supported by PhantomJS. Please use SwitchToRootFrame instead. - SwitchToParentFrame() error - - // SwitchToRootFrame focuses on the original, default page frame before any calls - // to Selection#Frame were made. After switching, all new and existing selections - // will refer to the root frame. All further Page methods will apply to this frame - // as well. - SwitchToRootFrame() error - - // SwitchToWindow switches to the first available window with the provided name - // (JavaScript `window.name` attribute). - SwitchToWindow(name string) error - - // NextWindow switches to the next available window. - NextWindow() error - - // CloseWindow closes the active window. - CloseWindow() error - - // WindowCount returns the number of available windows. - WindowCount() (int, error) - - // ReadLogs returns log messages of the provided log type. For example, - // page.ReadLogs("browser") returns browser console logs, such as JavaScript logs - // and errors. If the all argument is provided as true, all logs since the session - // was created are returned. Otherwise, only logs since the last call to ReadLogs - // are returned. Valid log types may be obtained using the LogTypes method. - ReadLogs(logType string, all ...bool) ([]Log, error) - - // LogTypes returns all of the valid log types that may be used with a LogReader. - LogTypes() ([]string, error) -} - -// A Log represents a single log message -type Log struct { - // Message is the text of the log message. - Message string - - // Location is the code location of the log message, if present - Location string - - // Level is the log level ("DEBUG", "INFO", "WARNING", or "SEVERE"). - Level string - - // Time is the time the message was logged. - Time time.Time -} - -func newPage(session *api.Session) Page { - pageSelection := &userSelection{selection.NewSelection(session)} - return &userPage{&page.Page{Session: session}, pageSelection} -} diff --git a/vendor/github.com/sclevine/agouti/core/selection.go b/vendor/github.com/sclevine/agouti/core/selection.go deleted file mode 100644 index 8c7ea61..0000000 --- a/vendor/github.com/sclevine/agouti/core/selection.go +++ /dev/null @@ -1,151 +0,0 @@ -package core - -// Selection instances refer to a selection of elements. -// Every Selection method is a valid MultiSelection method. -// -// Examples: -// -// selection.Find("table").All("tr").At(2).First("td input[type=checkbox]").Check() -// Checks the first checkbox in the third row of the only table. -// selection.Find("table").All("tr").Find("td").All("input[type=checkbox]").Check() -// Checks all checkboxes in the first-and-only cell of each row in the only table. -type Selection interface { - // Selections have Find*(), All*(), and First*() methods that return new sub-Selections - Selectable - - // String returns a string representation of the selection, ex. - // CSS: .some-class | XPath: //table [3] | Link "click me" [single] - String() string - - // Count returns the number of elements that the selection refers to. - Count() (int, error) - - // EqualsElement returns whether or not two selections of exactly - // one element each refer to the same element. - EqualsElement(comparable interface{}) (bool, error) - - // SwitchToFrame focuses on the frame specified by the selection. All new and - // existing selections will refer to the new frame. All further Page methods - // will apply to this frame as well. - SwitchToFrame() error - - // Click clicks on all of the elements that the selection refers to. - Click() error - - // DoubleClick double-clicks on all of the elements that the selection refers to. - DoubleClick() error - - // Fill fills all of the fields the selection refers to with the provided text. - Fill(text string) error - - // Check checks all of the unchecked checkboxes that the selection refers to. - Check() error - - // Uncheck unchecks all of the checked checkboxes that the selection refers to. - Uncheck() error - - // Select, when called on some number of elements that match the provided text. - Select(text string) error - - // Submit submits all selected forms. The selection may refer to a form itself - // or any input element contained within a form. - Submit() error - - // Text returns the entirety of the text content for exactly one element. - Text() (string, error) - - // Attribute returns an attribute value for exactly one element. - Attribute(attribute string) (string, error) - - // CSS returns a CSS style property value for exactly one element. - CSS(property string) (string, error) - - // Selected returns true if all of the elements that the selection refers to - // are selected. - Selected() (bool, error) - - // Visible returns true if all of the elements that the selection refers to - // are visible. - Visible() (bool, error) - - // Enabled returns true if all of the elements that the selection refers to - // are enabled. - Enabled() (bool, error) - - // Active returns true if the single element that the selection refers to is active. - Active() (bool, error) -} - -// A MultiSelection is a Selection that may be indexed using the At() method. -// -// A Selection returned by At() may still refer to multiple elements if any -// parent of the MultiSelection refers to multiple elements. -// -// Examples: -// selection.All("section").All("form").At(1).Submit() -// Submits the second form in each section. -// selection.All("div").Find("h1").Click() -// Clicks one h1 in each div, failing if any div does not contain exactly one h1. -type MultiSelection interface { - // All Selection methods are valid MultiSelection methods. - Selection - - // At finds the element at the provided index. - At(index int) Selection -} - -// Selectable methods apply their selectors to each element in the selection they -// are called on. If the selection they are called on refers to multiple -// elements, the resulting selection will refer to at least that many elements. -type Selectable interface { - // For each element in the current selection: - - // Find finds exactly one element by CSS selector. - Find(selector string) Selection - - // FindByXPath finds exactly one element by XPath selector. - FindByXPath(selector string) Selection - - // FindByLink finds exactly one anchor element by its text content. - FindByLink(text string) Selection - - // FindByLabel finds exactly one element by associated label text. - FindByLabel(text string) Selection - - // FindByButton finds exactly one button element with the provided text. - // Supports