Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: ios/web/public/test/web_view_interaction_test_util.mm

Issue 2275303004: Context menu egtests, plus related utilities. (Closed)
Patch Set: Reviewable. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/web/public/test/web_view_interaction_test_util.h" 5 #import "ios/web/public/test/web_view_interaction_test_util.h"
6 6
7 #import <Foundation/Foundation.h> 7 #include "base/mac/bind_objc_block.h"
8 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/ios/wait_util.h"
9 #include "ios/testing/earl_grey/wait_util.h" 11 #include "ios/testing/earl_grey/wait_util.h"
baxley 2016/08/31 05:27:02 Just an FYI. I am working on a CL to remove this d
marq (ping after 24h) 2016/08/31 13:07:58 Acknowledged.
12 #import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h"
13 #import "ios/web/web_state/crw_web_view_proxy_impl.h"
10 #import "ios/web/web_state/ui/crw_web_controller.h" 14 #import "ios/web/web_state/ui/crw_web_controller.h"
11 #include "ios/web/web_state/web_state_impl.h" 15 #include "ios/web/web_state/web_state_impl.h"
12 16
13 using web::NavigationManager; 17 using web::NavigationManager;
14 18
15 namespace web { 19 namespace web {
16 namespace test { 20 namespace test {
17 21
18 enum ElementAction { 22 enum ElementAction {
19 ELEMENT_ACTION_CLICK, 23 ELEMENT_ACTION_CLICK,
20 ELEMENT_ACTION_FOCUS, 24 ELEMENT_ACTION_FOCUS,
21 ELEMENT_ACTION_SUBMIT 25 ELEMENT_ACTION_SUBMIT
22 }; 26 };
23 27
28 std::unique_ptr<base::Value> ExecuteScript(web::WebState* web_state,
29 const std::string& script) {
30 __block std::unique_ptr<base::Value> result;
31 __block bool did_finish = false;
32 web_state->ExecuteJavaScript(base::UTF8ToUTF16(script),
33 base::BindBlock(^(const base::Value* value) {
34 if (value)
35 result = value->CreateDeepCopy();
36 did_finish = true;
37 }));
38
39 testing::WaitUntilCondition(testing::kWaitForJSCompletionTimeout, ^{
40 return did_finish;
41 });
42
43 // As result is marked __block, this return call does a copy and not a move
44 // (marking the variable as __block mean it is allocated in the block object
45 // and not the stack). Since the "return std::move()" pattern is discouraged
46 // use a local variable.
47 //
48 // Fixes the following compilation failure:
49 // ../web_view_matchers.mm:ll:cc: error: call to implicitly-deleted copy
50 // constructor of 'std::unique_ptr<base::Value>'
51 std::unique_ptr<base::Value> stack_result = std::move(result);
52 return stack_result;
53 }
54
55 CGRect BoundingRectOfElementWithId(web::WebState* web_state,
56 const std::string& element_id) {
57 std::string kGetBoundsScript =
58 "(function() {"
59 " var element = document.getElementById('" +
60 element_id +
61 "');"
62 " if (!element)"
63 " return {'error': 'Element " +
64 element_id +
65 " not found'};"
66 " var rect = element.getBoundingClientRect();"
67 " var top = rect.top + document.body.scrollTop;"
68 " var bottom = rect.bottom + document.body.scrollTop;"
69 " var left = rect.left + document.body.scrollLeft;"
70 " var right = rect.right + document.body.scrollLeft;"
71 " return {"
72 " 'left': left,"
73 " 'top': top,"
74 " 'width': right - left,"
75 " 'height': bottom - top,"
76 " 'document_width' : document.documentElement.scrollWidth,"
77 " 'document_height' : document.documentElement.scrollHeight,"
78 " };"
79 "})();";
80
81 std::unique_ptr<base::Value> value;
82 NSDate* deadline =
83 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout];
84 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && !value) {
85 value = ExecuteScript(web_state, kGetBoundsScript);
86 base::test::ios::SpinRunLoopWithMaxDelay(
87 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds));
88 }
89
90 CGRect bounds = CGRectZero;
Eugene But (OOO till 7-30) 2016/08/30 18:11:05 NIT: Do you need this variable? It's lifetime quit
marq (ping after 24h) 2016/08/31 13:07:58 Good catch, done.
91 base::DictionaryValue const* dictionary = nullptr;
92 bool marshalling_ok = value->GetAsDictionary(&dictionary);
93 std::string error;
94 // If there is in error, then that's not OK, so the GetString return value
95 // is negated here.
96 marshalling_ok = marshalling_ok && !dictionary->GetString("error", &error);
97 if (!marshalling_ok)
98 return bounds;
99
100 double left, top, width, height, document_width, document_height;
101 marshalling_ok = marshalling_ok && dictionary->GetDouble("left", &left) &&
102 dictionary->GetDouble("top", &top) &&
103 dictionary->GetDouble("width", &width) &&
104 dictionary->GetDouble("height", &height) &&
105 dictionary->GetDouble("document_width", &document_width) &&
106 dictionary->GetDouble("document_height", &document_height);
107
108 if (!marshalling_ok)
109 return bounds;
110
111 CRWWebController* web_controller =
112 static_cast<WebStateImpl*>(web_state)->GetWebController();
113
114 CGFloat scale = [[web_controller.webViewProxy scrollViewProxy] zoomScale];
Eugene But (OOO till 7-30) 2016/08/30 18:11:05 No need to use web controller here: web_state->Ge
marq (ping after 24h) 2016/08/31 13:07:58 Done.
115
116 bounds = CGRectMake(left * scale, top * scale, width * scale, height * scale);
117 return bounds;
118 }
119
24 // Returns whether the Javascript action specified by |action| ran on 120 // Returns whether the Javascript action specified by |action| ran on
25 // |element_id| in the passed |web_state|. 121 // |element_id| in the passed |web_state|.
26 bool RunActionOnWebViewElementWithId(web::WebState* web_state, 122 bool RunActionOnWebViewElementWithId(web::WebState* web_state,
27 const std::string& element_id, 123 const std::string& element_id,
28 ElementAction action) { 124 ElementAction action) {
29 CRWWebController* web_controller = 125 CRWWebController* web_controller =
30 static_cast<WebStateImpl*>(web_state)->GetWebController(); 126 static_cast<WebStateImpl*>(web_state)->GetWebController();
31 const char* js_action = nullptr; 127 const char* js_action = nullptr;
32 switch (action) { 128 switch (action) {
33 case ELEMENT_ACTION_CLICK: 129 case ELEMENT_ACTION_CLICK:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 174 }
79 175
80 bool SubmitWebViewFormWithId(web::WebState* web_state, 176 bool SubmitWebViewFormWithId(web::WebState* web_state,
81 const std::string& form_id) { 177 const std::string& form_id) {
82 return RunActionOnWebViewElementWithId(web_state, form_id, 178 return RunActionOnWebViewElementWithId(web_state, form_id,
83 ELEMENT_ACTION_SUBMIT); 179 ELEMENT_ACTION_SUBMIT);
84 } 180 }
85 181
86 } // namespace test 182 } // namespace test
87 } // namespace web 183 } // namespace web
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698