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

Side by Side Diff: ios/chrome/browser/web/forms_egtest.mm

Issue 2961483002: Refactor PostOnSamePage test to ensure the form is posted. (Closed)
Patch Set: Move to form_egtest Created 3 years, 5 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
« no previous file with comments | « ios/chrome/browser/web/browsing_egtest.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <XCTest/XCTest.h> 5 #import <XCTest/XCTest.h>
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
10 #include "components/strings/grit/components_strings.h" 10 #include "components/strings/grit/components_strings.h"
11 #include "ios/chrome/browser/ui/ui_util.h" 11 #include "ios/chrome/browser/ui/ui_util.h"
12 #import "ios/chrome/test/app/chrome_test_util.h" 12 #import "ios/chrome/test/app/chrome_test_util.h"
13 #include "ios/chrome/test/app/navigation_test_util.h" 13 #include "ios/chrome/test/app/navigation_test_util.h"
14 #include "ios/chrome/test/app/web_view_interaction_test_util.h" 14 #include "ios/chrome/test/app/web_view_interaction_test_util.h"
15 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" 15 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
16 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" 16 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
17 #import "ios/chrome/test/earl_grey/chrome_matchers.h" 17 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
18 #import "ios/chrome/test/earl_grey/chrome_test_case.h" 18 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
19 #import "ios/testing/wait_util.h" 19 #import "ios/testing/wait_util.h"
20 #import "ios/web/public/test/earl_grey/web_view_actions.h"
21 #import "ios/web/public/test/earl_grey/web_view_matchers.h"
20 #include "ios/web/public/test/http_server/data_response_provider.h" 22 #include "ios/web/public/test/http_server/data_response_provider.h"
21 #import "ios/web/public/test/http_server/http_server.h" 23 #import "ios/web/public/test/http_server/http_server.h"
22 #include "ios/web/public/test/http_server/http_server_util.h" 24 #include "ios/web/public/test/http_server/http_server_util.h"
23 #include "ios/web/public/test/url_test_util.h" 25 #include "ios/web/public/test/url_test_util.h"
24 26
25 #if !defined(__has_feature) || !__has_feature(objc_arc) 27 #if !defined(__has_feature) || !__has_feature(objc_arc)
26 #error "This file requires ARC support." 28 #error "This file requires ARC support."
27 #endif 29 #endif
28 30
29 using chrome_test_util::ButtonWithAccessibilityLabelId; 31 using chrome_test_util::ButtonWithAccessibilityLabelId;
(...skipping 18 matching lines...) Expand all
48 // GURL of a generic website in the user navigation flow. 50 // GURL of a generic website in the user navigation flow.
49 const GURL GetGenericUrl() { 51 const GURL GetGenericUrl() {
50 return web::test::HttpServer::MakeUrl("http://generic"); 52 return web::test::HttpServer::MakeUrl("http://generic");
51 } 53 }
52 54
53 // GURL of a page with a form that posts data to |GetDestinationUrl|. 55 // GURL of a page with a form that posts data to |GetDestinationUrl|.
54 const GURL GetFormUrl() { 56 const GURL GetFormUrl() {
55 return web::test::HttpServer::MakeUrl("http://form"); 57 return web::test::HttpServer::MakeUrl("http://form");
56 } 58 }
57 59
60 // GURL of a page with a form that posts data to |GetDestinationUrl|.
61 const GURL GetFormPostOnSamePageUrl() {
62 return web::test::HttpServer::MakeUrl("http://form");
63 }
64
58 // GURL of the page to which the |GetFormUrl| posts data to. 65 // GURL of the page to which the |GetFormUrl| posts data to.
59 const GURL GetDestinationUrl() { 66 const GURL GetDestinationUrl() {
60 return web::test::HttpServer::MakeUrl("http://destination"); 67 return web::test::HttpServer::MakeUrl("http://destination");
61 } 68 }
62 69
63 #pragma mark - TestFormRedirectResponseProvider 70 #pragma mark - TestFormResponseProvider
64 71
65 // URL that redirects to |GetDestinationUrl| with a 302. 72 // URL that redirects to |GetDestinationUrl| with a 302.
66 const GURL GetRedirectUrl() { 73 const GURL GetRedirectUrl() {
67 return web::test::HttpServer::MakeUrl("http://redirect"); 74 return web::test::HttpServer::MakeUrl("http://redirect");
68 } 75 }
69 76
70 // URL to return a page that posts to |GetRedirectUrl|. 77 // URL to return a page that posts to |GetRedirectUrl|.
71 const GURL GetRedirectFormUrl() { 78 const GURL GetRedirectFormUrl() {
72 return web::test::HttpServer::MakeUrl("http://formRedirect"); 79 return web::test::HttpServer::MakeUrl("http://formRedirect");
73 } 80 }
74 81
75 // A ResponseProvider that provides html response or a redirect. 82 // A ResponseProvider that provides html response, post response or a redirect.
76 class TestFormRedirectResponseProvider : public web::DataResponseProvider { 83 class TestFormResponseProvider : public web::DataResponseProvider {
77 public: 84 public:
78 // TestResponseProvider implementation. 85 // TestResponseProvider implementation.
79 bool CanHandleRequest(const Request& request) override; 86 bool CanHandleRequest(const Request& request) override;
80 void GetResponseHeadersAndBody( 87 void GetResponseHeadersAndBody(
81 const Request& request, 88 const Request& request,
82 scoped_refptr<net::HttpResponseHeaders>* headers, 89 scoped_refptr<net::HttpResponseHeaders>* headers,
83 std::string* response_body) override; 90 std::string* response_body) override;
84 }; 91 };
85 92
86 bool TestFormRedirectResponseProvider::CanHandleRequest( 93 bool TestFormResponseProvider::CanHandleRequest(const Request& request) {
87 const Request& request) {
88 const GURL& url = request.url; 94 const GURL& url = request.url;
89 return url == GetDestinationUrl() || url == GetRedirectUrl() || 95 return url == GetDestinationUrl() || url == GetRedirectUrl() ||
90 url == GetRedirectFormUrl(); 96 url == GetRedirectFormUrl() || url == GetFormPostOnSamePageUrl() ||
97 url == GetGenericUrl();
91 } 98 }
92 99
93 void TestFormRedirectResponseProvider::GetResponseHeadersAndBody( 100 void TestFormResponseProvider::GetResponseHeadersAndBody(
94 const Request& request, 101 const Request& request,
95 scoped_refptr<net::HttpResponseHeaders>* headers, 102 scoped_refptr<net::HttpResponseHeaders>* headers,
96 std::string* response_body) { 103 std::string* response_body) {
97 const GURL& url = request.url; 104 const GURL& url = request.url;
98 if (url == GetRedirectUrl()) { 105 if (url == GetRedirectUrl()) {
99 *headers = web::ResponseProvider::GetRedirectResponseHeaders( 106 *headers = web::ResponseProvider::GetRedirectResponseHeaders(
100 GetDestinationUrl().spec(), net::HTTP_FOUND); 107 GetDestinationUrl().spec(), net::HTTP_FOUND);
101 return; 108 return;
102 } 109 }
103 110
104 *headers = web::ResponseProvider::GetDefaultResponseHeaders(); 111 *headers = web::ResponseProvider::GetDefaultResponseHeaders();
112 if (url == GetGenericUrl()) {
113 *response_body = "A generic page";
114 return;
115 }
116 if (url == GetFormPostOnSamePageUrl()) {
117 if (request.method == "POST") {
118 *response_body = request.method + std::string(" ") + request.body;
119 } else {
120 *response_body =
121 "<form method='post'>"
122 "<input value='button' type='submit' id='button'></form>";
123 }
124 return;
125 }
126
105 if (url == GetRedirectFormUrl()) { 127 if (url == GetRedirectFormUrl()) {
106 *response_body = 128 *response_body =
107 base::StringPrintf(kFormHtmlTemplate, GetRedirectUrl().spec().c_str()); 129 base::StringPrintf(kFormHtmlTemplate, GetRedirectUrl().spec().c_str());
108 return; 130 return;
109 } else if (url == GetDestinationUrl()) { 131 } else if (url == GetDestinationUrl()) {
110 *response_body = request.method + std::string(" ") + request.body; 132 *response_body = request.method + std::string(" ") + request.body;
111 return; 133 return;
112 } 134 }
113 NOTREACHED(); 135 NOTREACHED();
114 } 136 }
115 137
116 } // namespace 138 } // namespace
117 139
118 // Tests submition of HTTP forms POST data including cases involving navigation. 140 // Tests submition of HTTP forms POST data including cases involving navigation.
119 @interface FormsTestCase : ChromeTestCase 141 @interface FormsTestCase : ChromeTestCase
120 @end 142 @end
121 143
122 @implementation FormsTestCase 144 @implementation FormsTestCase
123 145
146 // Matcher for a Go button that is interactable.
147 id<GREYMatcher> GoButtonMatcher() {
148 return grey_allOf(grey_accessibilityID(@"Go"), grey_interactable(), nil);
149 }
150
124 // Waits for view with Tab History accessibility ID. 151 // Waits for view with Tab History accessibility ID.
125 - (void)waitForTabHistoryView { 152 - (void)waitForTabHistoryView {
126 GREYCondition* condition = [GREYCondition 153 GREYCondition* condition = [GREYCondition
127 conditionWithName:@"Waiting for Tab History to display." 154 conditionWithName:@"Waiting for Tab History to display."
128 block:^BOOL { 155 block:^BOOL {
129 NSError* error = nil; 156 NSError* error = nil;
130 id<GREYMatcher> tabHistory = 157 id<GREYMatcher> tabHistory =
131 grey_accessibilityID(@"Tab History"); 158 grey_accessibilityID(@"Tab History");
132 [[EarlGrey selectElementWithMatcher:tabHistory] 159 [[EarlGrey selectElementWithMatcher:tabHistory]
133 assertWithMatcher:grey_notNil() 160 assertWithMatcher:grey_notNil()
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // Go back and verify the browser navigates to the original URL. 347 // Go back and verify the browser navigates to the original URL.
321 [ChromeEarlGrey goBack]; 348 [ChromeEarlGrey goBack];
322 [[EarlGrey selectElementWithMatcher:WebViewContainingText(kSubmitButtonLabel)] 349 [[EarlGrey selectElementWithMatcher:WebViewContainingText(kSubmitButtonLabel)]
323 assertWithMatcher:grey_notNil()]; 350 assertWithMatcher:grey_notNil()];
324 [[EarlGrey selectElementWithMatcher:OmniboxText(GetFormUrl().GetContent())] 351 [[EarlGrey selectElementWithMatcher:OmniboxText(GetFormUrl().GetContent())]
325 assertWithMatcher:grey_notNil()]; 352 assertWithMatcher:grey_notNil()];
326 } 353 }
327 354
328 // Tests that a POST followed by a redirect does not show the popup. 355 // Tests that a POST followed by a redirect does not show the popup.
329 - (void)testRepostFormCancellingAfterRedirect { 356 - (void)testRepostFormCancellingAfterRedirect {
330 web::test::SetUpHttpServer( 357 web::test::SetUpHttpServer(base::MakeUnique<TestFormResponseProvider>());
331 base::MakeUnique<TestFormRedirectResponseProvider>());
332 const GURL destinationURL = GetDestinationUrl(); 358 const GURL destinationURL = GetDestinationUrl();
333 359
334 [ChromeEarlGrey loadURL:GetRedirectFormUrl()]; 360 [ChromeEarlGrey loadURL:GetRedirectFormUrl()];
335 361
336 // Submit the form, which redirects before printing the data. 362 // Submit the form, which redirects before printing the data.
337 chrome_test_util::TapWebViewElementWithId(kSubmitButtonLabel); 363 chrome_test_util::TapWebViewElementWithId(kSubmitButtonLabel);
338 364
339 // Check that the redirect changes the POST to a GET. 365 // Check that the redirect changes the POST to a GET.
340 [[EarlGrey selectElementWithMatcher:WebViewContainingText("GET")] 366 [[EarlGrey selectElementWithMatcher:WebViewContainingText("GET")]
341 assertWithMatcher:grey_notNil()]; 367 assertWithMatcher:grey_notNil()];
342 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())] 368 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
343 assertWithMatcher:grey_notNil()]; 369 assertWithMatcher:grey_notNil()];
344 370
345 [ChromeEarlGrey reload]; 371 [ChromeEarlGrey reload];
346 372
347 // Check that the popup did not show 373 // Check that the popup did not show
348 id<GREYMatcher> resendWarning = 374 id<GREYMatcher> resendWarning =
349 ButtonWithAccessibilityLabelId(IDS_HTTP_POST_WARNING_RESEND); 375 ButtonWithAccessibilityLabelId(IDS_HTTP_POST_WARNING_RESEND);
350 [[EarlGrey selectElementWithMatcher:resendWarning] 376 [[EarlGrey selectElementWithMatcher:resendWarning]
351 assertWithMatcher:grey_nil()]; 377 assertWithMatcher:grey_nil()];
352 [[EarlGrey selectElementWithMatcher:WebViewContainingText("GET")] 378 [[EarlGrey selectElementWithMatcher:WebViewContainingText("GET")]
353 assertWithMatcher:grey_notNil()]; 379 assertWithMatcher:grey_notNil()];
354 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())] 380 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
355 assertWithMatcher:grey_notNil()]; 381 assertWithMatcher:grey_notNil()];
356 } 382 }
357 383
384 // Tests that pressing the button on a POST-based form with same-page action
385 // does not change the page URL and that the back button works as expected
386 // afterwards.
387 - (void)testPostFormToSamePage {
388 // TODO(crbug.com/714303): Re-enable this test on devices.
389 #if !TARGET_IPHONE_SIMULATOR
390 EARL_GREY_TEST_DISABLED(@"Test disabled on device.");
391 #endif
392
393 web::test::SetUpHttpServer(base::MakeUnique<TestFormResponseProvider>());
394 // Open the first URL so it's in history.
395 [ChromeEarlGrey loadURL:GetGenericUrl()];
396
397 // Open the second URL, tap the button, and verify the browser navigates to
398 // the expected URL.
399 [ChromeEarlGrey loadURL:GetFormPostOnSamePageUrl()];
400 chrome_test_util::TapWebViewElementWithId("button");
401 [ChromeEarlGrey waitForWebViewContainingText:"POST"];
402 [[EarlGrey
403 selectElementWithMatcher:OmniboxText(
404 GetFormPostOnSamePageUrl().GetContent())]
Eugene But (OOO till 7-30) 2017/06/24 01:32:20 nit: Do you want to use a local variable for this
405 assertWithMatcher:grey_notNil()];
406
407 // Go back once and verify the browser navigates to the form URL.
408 [ChromeEarlGrey goBack];
409 [[EarlGrey
410 selectElementWithMatcher:OmniboxText(
411 GetFormPostOnSamePageUrl().GetContent())]
412 assertWithMatcher:grey_notNil()];
413
414 // Go back a second time and verify the browser navigates to the first URL.
415 [ChromeEarlGrey goBack];
416 [[EarlGrey selectElementWithMatcher:OmniboxText(GetGenericUrl().GetContent())]
417 assertWithMatcher:grey_notNil()];
418 }
419
420 // Tests that submitting a POST-based form by tapping the 'Go' button on the
421 // keyboard navigates to the correct URL and the back button works as expected
422 // afterwards.
423 - (void)testPostFormEntryWithKeyboard {
424 // TODO(crbug.com/704618): Re-enable this test on devices.
425 #if !TARGET_IPHONE_SIMULATOR
426 EARL_GREY_TEST_DISABLED(@"Test disabled on device.");
427 #endif
428
429 [self setUpFormTestSimpleHttpServer];
430 const GURL destinationURL = GetDestinationUrl();
431
432 [ChromeEarlGrey loadURL:GetFormUrl()];
433 [self submitFormUsingKeyboardGoButtonWithInputID:"textfield"];
434
435 // Verify that the browser navigates to the expected URL.
436 [ChromeEarlGrey waitForWebViewContainingText:"bar!"];
437 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
438 assertWithMatcher:grey_notNil()];
439
440 // Go back and verify that the browser navigates to the original URL.
441 [ChromeEarlGrey goBack];
442 [[EarlGrey selectElementWithMatcher:OmniboxText(GetFormUrl().GetContent())]
443 assertWithMatcher:grey_notNil()];
444 }
445
446 // Tap the text field indicated by |ID| to open the keyboard, and then
447 // press the keyboard's "Go" button to submit the form.
448 - (void)submitFormUsingKeyboardGoButtonWithInputID:(const std::string&)ID {
449 // Disable EarlGrey's synchronization since it is blocked by opening the
450 // keyboard from a web view.
451 [[GREYConfiguration sharedInstance]
452 setValue:@NO
453 forConfigKey:kGREYConfigKeySynchronizationEnabled];
454
455 // Wait for web view to be interactable before tapping.
456 GREYCondition* interactableCondition = [GREYCondition
457 conditionWithName:@"Wait for web view to be interactable."
458 block:^BOOL {
459 NSError* error = nil;
460 id<GREYMatcher> webViewMatcher = WebViewInWebState(
461 chrome_test_util::GetCurrentWebState());
462 [[EarlGrey selectElementWithMatcher:webViewMatcher]
463 assertWithMatcher:grey_interactable()
464 error:&error];
465 return !error;
466 }];
467 GREYAssert(
468 [interactableCondition waitWithTimeout:testing::kWaitForUIElementTimeout],
469 @"Web view did not become interactable.");
470
471 web::WebState* currentWebState = chrome_test_util::GetCurrentWebState();
472 [[EarlGrey selectElementWithMatcher:web::WebViewInWebState(currentWebState)]
473 performAction:web::WebViewTapElement(currentWebState, ID)];
474
475 // Wait until the keyboard shows up before tapping.
476 GREYCondition* condition = [GREYCondition
477 conditionWithName:@"Wait for the keyboard to show up."
478 block:^BOOL {
479 NSError* error = nil;
480 [[EarlGrey selectElementWithMatcher:GoButtonMatcher()]
481 assertWithMatcher:grey_notNil()
482 error:&error];
483 return (error == nil);
484 }];
485 GREYAssert([condition waitWithTimeout:10],
Eugene But (OOO till 7-30) 2017/06/24 01:32:20 Do we need a constant for this timeout?
486 @"No keyboard with 'Go' button showed up.");
487
488 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")]
489 performAction:grey_tap()];
490
491 // Reenable synchronization now that the keyboard has been closed.
492 [[GREYConfiguration sharedInstance]
493 setValue:@YES
494 forConfigKey:kGREYConfigKeySynchronizationEnabled];
495 }
496
358 @end 497 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/web/browsing_egtest.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698