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

Side by Side Diff: ios/web/public/test/earl_grey/web_view_matchers.mm

Issue 2275303004: Context menu egtests, plus related utilities. (Closed)
Patch Set: Review feedback plus some fixes and tweaks. 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/earl_grey/web_view_matchers.h" 5 #import "ios/web/public/test/earl_grey/web_view_matchers.h"
6 6
7 #include <memory>
8
9 #import <WebKit/WebKit.h> 7 #import <WebKit/WebKit.h>
10 8
11 #include "base/mac/bind_objc_block.h" 9 #include "base/mac/bind_objc_block.h"
12 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
13 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
15 #include "base/test/ios/wait_util.h" 13 #include "base/test/ios/wait_util.h"
16 #include "base/values.h" 14 #include "base/values.h"
17 #include "ios/testing/earl_grey/wait_util.h" 15 #include "ios/testing/earl_grey/wait_util.h"
16 #import "ios/web/public/test/web_view_interaction_test_util.h"
17
18 using web::test::ExecuteJavaScript;
18 19
19 namespace { 20 namespace {
20 21
21 // Script that returns document.body as a string. 22 // Script that returns document.body as a string.
22 char kGetDocumentBodyJavaScript[] = 23 char kGetDocumentBodyJavaScript[] =
23 "document.body ? document.body.textContent : null"; 24 "document.body ? document.body.textContent : null";
24 // Script that tests presence of css selector. 25 // Script that tests presence of css selector.
25 char kTestCssSelectorJavaScriptTemplate[] = "!!document.querySelector(\"%s\");"; 26 char kTestCssSelectorJavaScriptTemplate[] = "!!document.querySelector(\"%s\");";
26 27
27 // Synchronously returns the result of executed JavaScript.
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 } // namespace 28 } // namespace
56 29
57 namespace web { 30 namespace web {
58 31
59 id<GREYMatcher> webViewInWebState(WebState* web_state) { 32 id<GREYMatcher> webViewInWebState(WebState* web_state) {
60 MatchesBlock matches = ^BOOL(UIView* view) { 33 MatchesBlock matches = ^BOOL(UIView* view) {
61 return [view isKindOfClass:[WKWebView class]] && 34 return [view isKindOfClass:[WKWebView class]] &&
62 [view isDescendantOfView:web_state->GetView()]; 35 [view isDescendantOfView:web_state->GetView()];
63 }; 36 };
64 37
65 DescribeToBlock describe = ^(id<GREYDescription> description) { 38 DescribeToBlock describe = ^(id<GREYDescription> description) {
66 [description appendText:@"web view in web state"]; 39 [description appendText:@"web view in web state"];
67 }; 40 };
68 41
69 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches 42 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
70 descriptionBlock:describe] 43 descriptionBlock:describe]
71 autorelease]; 44 autorelease];
72 } 45 }
73 46
74 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { 47 id<GREYMatcher> webViewContainingText(const std::string& text,
Eugene But (OOO till 7-30) 2016/08/31 15:27:59 This should be string by value or local variable (
48 WebState* web_state) {
75 MatchesBlock matches = ^BOOL(WKWebView*) { 49 MatchesBlock matches = ^BOOL(WKWebView*) {
76 __block BOOL did_succeed = NO; 50 __block BOOL did_succeed = NO;
77 NSDate* deadline = 51 NSDate* deadline =
78 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; 52 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout];
79 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && 53 while (([[NSDate date] compare:deadline] != NSOrderedDescending) &&
80 !did_succeed) { 54 !did_succeed) {
81 std::unique_ptr<base::Value> value = 55 std::unique_ptr<base::Value> value =
82 ExecuteScript(web_state, kGetDocumentBodyJavaScript); 56 ExecuteJavaScript(web_state, kGetDocumentBodyJavaScript);
83 std::string body; 57 std::string body;
84 if (value && value->GetAsString(&body)) { 58 if (value && value->GetAsString(&body)) {
85 did_succeed = body.find(text) != std::string::npos; 59 did_succeed = body.find(text) != std::string::npos;
86 } 60 }
87 base::test::ios::SpinRunLoopWithMaxDelay( 61 base::test::ios::SpinRunLoopWithMaxDelay(
88 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); 62 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds));
89 } 63 }
90 return did_succeed; 64 return did_succeed;
91 }; 65 };
92 66
93 DescribeToBlock describe = ^(id<GREYDescription> description) { 67 DescribeToBlock describe = ^(id<GREYDescription> description) {
94 [description appendText:@"web view containing "]; 68 [description appendText:@"web view containing "];
95 [description appendText:base::SysUTF8ToNSString(text)]; 69 [description appendText:base::SysUTF8ToNSString(text)];
96 }; 70 };
97 71
98 return grey_allOf(webViewInWebState(web_state), 72 return grey_allOf(webViewInWebState(web_state),
99 [[[GREYElementMatcherBlock alloc] 73 [[[GREYElementMatcherBlock alloc]
100 initWithMatchesBlock:matches 74 initWithMatchesBlock:matches
101 descriptionBlock:describe] autorelease], 75 descriptionBlock:describe] autorelease],
102 nil); 76 nil);
103 } 77 }
104 78
105 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, 79 id<GREYMatcher> webViewContainingBlockedImage(const std::string& image_id,
Eugene But (OOO till 7-30) 2016/08/31 15:27:59 ditto
106 CGSize expected_size, 80 CGSize expected_size,
107 WebState* web_state) { 81 WebState* web_state) {
108 MatchesBlock matches = ^BOOL(WKWebView*) { 82 MatchesBlock matches = ^BOOL(WKWebView*) {
109 __block BOOL did_succeed = NO; 83 __block BOOL did_succeed = NO;
110 NSDate* deadline = 84 NSDate* deadline =
111 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; 85 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout];
112 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && 86 while (([[NSDate date] compare:deadline] != NSOrderedDescending) &&
113 !did_succeed) { 87 !did_succeed) {
114 NSString* const kGetElementAttributesScript = [NSString 88 NSString* const kGetElementAttributesScript = [NSString
115 stringWithFormat:@"var image = document.getElementById('%@');" 89 stringWithFormat:@"var image = document.getElementById('%@');"
116 @"var imageHeight = image.height;" 90 @"var imageHeight = image.height;"
117 @"var imageWidth = image.width;" 91 @"var imageWidth = image.width;"
118 @"JSON.stringify({" 92 @"JSON.stringify({"
119 @" height:imageHeight," 93 @" height:imageHeight,"
120 @" width:imageWidth" 94 @" width:imageWidth"
121 @"});", 95 @"});",
122 base::SysUTF8ToNSString(image_id)]; 96 base::SysUTF8ToNSString(image_id)];
123 std::unique_ptr<base::Value> value = ExecuteScript( 97 std::unique_ptr<base::Value> value = ExecuteJavaScript(
124 web_state, base::SysNSStringToUTF8(kGetElementAttributesScript)); 98 web_state, base::SysNSStringToUTF8(kGetElementAttributesScript));
125 std::string result; 99 std::string result;
126 if (value && value->GetAsString(&result)) { 100 if (value && value->GetAsString(&result)) {
127 NSString* evaluation_result = base::SysUTF8ToNSString(result); 101 NSString* evaluation_result = base::SysUTF8ToNSString(result);
128 NSData* image_attributes_as_data = 102 NSData* image_attributes_as_data =
129 [evaluation_result dataUsingEncoding:NSUTF8StringEncoding]; 103 [evaluation_result dataUsingEncoding:NSUTF8StringEncoding];
130 NSDictionary* image_attributes = 104 NSDictionary* image_attributes =
131 [NSJSONSerialization JSONObjectWithData:image_attributes_as_data 105 [NSJSONSerialization JSONObjectWithData:image_attributes_as_data
132 options:0 106 options:0
133 error:nil]; 107 error:nil];
(...skipping 13 matching lines...) Expand all
147 [description appendText:base::SysUTF8ToNSString(image_id)]; 121 [description appendText:base::SysUTF8ToNSString(image_id)];
148 }; 122 };
149 123
150 return grey_allOf(webViewInWebState(web_state), 124 return grey_allOf(webViewInWebState(web_state),
151 [[[GREYElementMatcherBlock alloc] 125 [[[GREYElementMatcherBlock alloc]
152 initWithMatchesBlock:matches 126 initWithMatchesBlock:matches
153 descriptionBlock:describe] autorelease], 127 descriptionBlock:describe] autorelease],
154 nil); 128 nil);
155 } 129 }
156 130
157 id<GREYMatcher> webViewCssSelector(std::string selector, WebState* web_state) { 131 id<GREYMatcher> webViewCssSelector(const std::string& selector,
Eugene But (OOO till 7-30) 2016/08/31 15:27:59 ditto
132 WebState* web_state) {
158 MatchesBlock matches = ^BOOL(WKWebView*) { 133 MatchesBlock matches = ^BOOL(WKWebView*) {
159 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, 134 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate,
160 selector.c_str()); 135 selector.c_str());
161 __block bool did_succeed = false; 136 __block bool did_succeed = false;
162 NSDate* deadline = 137 NSDate* deadline =
163 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; 138 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout];
164 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && 139 while (([[NSDate date] compare:deadline] != NSOrderedDescending) &&
165 !did_succeed) { 140 !did_succeed) {
166 std::unique_ptr<base::Value> value = ExecuteScript(web_state, script); 141 std::unique_ptr<base::Value> value = ExecuteJavaScript(web_state, script);
167 if (value) 142 if (value)
168 value->GetAsBoolean(&did_succeed); 143 value->GetAsBoolean(&did_succeed);
169 base::test::ios::SpinRunLoopWithMaxDelay( 144 base::test::ios::SpinRunLoopWithMaxDelay(
170 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); 145 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds));
171 } 146 }
172 return did_succeed; 147 return did_succeed;
173 }; 148 };
174 149
175 DescribeToBlock describe = ^(id<GREYDescription> description) { 150 DescribeToBlock describe = ^(id<GREYDescription> description) {
176 [description appendText:@"web view selector "]; 151 [description appendText:@"web view selector "];
(...skipping 17 matching lines...) Expand all
194 DescribeToBlock describe = ^(id<GREYDescription> description) { 169 DescribeToBlock describe = ^(id<GREYDescription> description) {
195 [description appendText:@"web view scroll view"]; 170 [description appendText:@"web view scroll view"];
196 }; 171 };
197 172
198 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches 173 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
199 descriptionBlock:describe] 174 descriptionBlock:describe]
200 autorelease]; 175 autorelease];
201 } 176 }
202 177
203 } // namespace web 178 } // namespace web
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698