Commit b3d75f5b authored by Olivier Robin's avatar Olivier Robin Committed by Commit Bot

Fix tests with WebFrame messaging

These are fixes that are needed to enable Autofill in iframes.
It also add more tests for the frame messaging logic.

Bug: 881364
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: Iea417c1d371094489daca66e7477d963d003c716
Reviewed-on: https://chromium-review.googlesource.com/1234333
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593282}
parent d09dd693
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/task_scheduler/task_scheduler.h" #include "base/task/task_scheduler/task_scheduler.h"
#import "base/test/ios/wait_util.h"
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/autofill_metrics.h"
...@@ -181,6 +182,10 @@ class AutofillControllerTest : public ChromeWebTest { ...@@ -181,6 +182,10 @@ class AutofillControllerTest : public ChromeWebTest {
// |retrieveSuggestionsForForm| to avoid considering a former call. // |retrieveSuggestionsForForm| to avoid considering a former call.
void WaitForSuggestionRetrieval(BOOL wait_for_trigger); void WaitForSuggestionRetrieval(BOOL wait_for_trigger);
// Blocks until |expected_size| forms have been fecthed.
bool WaitForFormFetched(AutofillManager* manager,
size_t expected_size) WARN_UNUSED_RESULT;
// Fails if the specified metric was not registered the given number of times. // Fails if the specified metric was not registered the given number of times.
void ExpectMetric(const std::string& histogram_name, int sum); void ExpectMetric(const std::string& histogram_name, int sum);
...@@ -265,6 +270,14 @@ void AutofillControllerTest::WaitForSuggestionRetrieval(BOOL wait_for_trigger) { ...@@ -265,6 +270,14 @@ void AutofillControllerTest::WaitForSuggestionRetrieval(BOOL wait_for_trigger) {
}); });
} }
bool AutofillControllerTest::WaitForFormFetched(AutofillManager* manager,
size_t expected_size) {
return base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForPageLoadTimeout, ^bool {
return manager->form_structures().size() == expected_size;
});
}
void AutofillControllerTest::ExpectMetric(const std::string& histogram_name, void AutofillControllerTest::ExpectMetric(const std::string& histogram_name,
int sum) { int sum) {
histogram_tester_->ExpectBucketCount(histogram_name, sum, 1); histogram_tester_->ExpectBucketCount(histogram_name, sum, 1);
...@@ -283,8 +296,8 @@ TEST_F(AutofillControllerTest, ReadForm) { ...@@ -283,8 +296,8 @@ TEST_F(AutofillControllerTest, ReadForm) {
AutofillManager* autofill_manager = AutofillManager* autofill_manager =
AutofillDriverIOS::FromWebStateAndWebFrame(web_state(), main_frame) AutofillDriverIOS::FromWebStateAndWebFrame(web_state(), main_frame)
->autofill_manager(); ->autofill_manager();
EXPECT_TRUE(WaitForFormFetched(autofill_manager, 1));
const auto& forms = autofill_manager->form_structures(); const auto& forms = autofill_manager->form_structures();
ASSERT_EQ(1U, forms.size());
const auto& form = *(forms.begin()->second); const auto& form = *(forms.begin()->second);
CheckField(form, NAME_FULL, "name_1"); CheckField(form, NAME_FULL, "name_1");
CheckField(form, ADDRESS_HOME_LINE1, "address_1"); CheckField(form, ADDRESS_HOME_LINE1, "address_1");
...@@ -304,8 +317,8 @@ TEST_F(AutofillControllerTest, ReadFormName) { ...@@ -304,8 +317,8 @@ TEST_F(AutofillControllerTest, ReadFormName) {
AutofillManager* autofill_manager = AutofillManager* autofill_manager =
AutofillDriverIOS::FromWebStateAndWebFrame(web_state(), main_frame) AutofillDriverIOS::FromWebStateAndWebFrame(web_state(), main_frame)
->autofill_manager(); ->autofill_manager();
EXPECT_TRUE(WaitForFormFetched(autofill_manager, 1));
const auto& forms = autofill_manager->form_structures(); const auto& forms = autofill_manager->form_structures();
ASSERT_EQ(1U, forms.size());
const auto& form = *(forms.begin()->second); const auto& form = *(forms.begin()->second);
EXPECT_EQ(base::UTF8ToUTF16("form1"), form.ToFormData().name); EXPECT_EQ(base::UTF8ToUTF16("form1"), form.ToFormData().name);
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_features.h"
#import "components/autofill/ios/browser/autofill_agent.h" #import "components/autofill/ios/browser/autofill_agent.h"
#include "components/autofill/ios/browser/autofill_driver_ios.h" #include "components/autofill/ios/browser/autofill_driver_ios.h"
#include "ios/chrome/browser/autofill/address_normalizer_factory.h"
#import "ios/chrome/browser/autofill/autofill_controller.h" #import "ios/chrome/browser/autofill/autofill_controller.h"
#import "ios/chrome/browser/autofill/form_suggestion_controller.h" #import "ios/chrome/browser/autofill/form_suggestion_controller.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
...@@ -136,6 +137,10 @@ FormStructureBrowserTest::FormStructureBrowserTest() ...@@ -136,6 +137,10 @@ FormStructureBrowserTest::FormStructureBrowserTest()
void FormStructureBrowserTest::SetUp() { void FormStructureBrowserTest::SetUp() {
ChromeWebTest::SetUp(); ChromeWebTest::SetUp();
// AddressNormalizerFactory must be initialized in a blocking allowed scoped.
// Initialize it now as it may DCHECK if it is initialized during the test.
AddressNormalizerFactory::GetInstance();
IOSSecurityStateTabHelper::CreateForWebState(web_state()); IOSSecurityStateTabHelper::CreateForWebState(web_state());
InfoBarManagerImpl::CreateForWebState(web_state()); InfoBarManagerImpl::CreateForWebState(web_state());
AutofillAgent* autofillAgent = [[AutofillAgent alloc] AutofillAgent* autofillAgent = [[AutofillAgent alloc]
......
...@@ -248,11 +248,16 @@ TEST_F(JsAutofillManagerTest, FillActiveFormField) { ...@@ -248,11 +248,16 @@ TEST_F(JsAutofillManagerTest, FillActiveFormField) {
data->SetString("name", "email"); data->SetString("name", "email");
data->SetString("identifier", "email"); data->SetString("identifier", "email");
data->SetString("value", "newemail@com"); data->SetString("value", "newemail@com");
__block BOOL block_was_called = NO;
[manager_ fillActiveFormField:std::move(data) [manager_ fillActiveFormField:std::move(data)
inFrame:web::GetMainWebFrame(web_state()) inFrame:web::GetMainWebFrame(web_state())
completionHandler:^{ completionHandler:^{
block_was_called = YES;
}]; }];
EXPECT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForActionTimeout, ^bool() {
return block_was_called;
}));
NSString* element_value_javascript = NSString* element_value_javascript =
[NSString stringWithFormat:@"%@.value", get_element_javascript]; [NSString stringWithFormat:@"%@.value", get_element_javascript];
EXPECT_NSEQ(@"newemail@com", ExecuteJavaScript(element_value_javascript)); EXPECT_NSEQ(@"newemail@com", ExecuteJavaScript(element_value_javascript));
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/web/public/features.h"
#import "ios/web/public/navigation_manager.h" #import "ios/web/public/navigation_manager.h"
#include "ios/web/public/test/http_server/html_response_provider.h" #include "ios/web/public/test/http_server/html_response_provider.h"
#import "ios/web/public/test/http_server/http_server.h" #import "ios/web/public/test/http_server/http_server.h"
...@@ -560,9 +561,18 @@ class PausableResponseProvider : public HtmlResponseProvider { ...@@ -560,9 +561,18 @@ class PausableResponseProvider : public HtmlResponseProvider {
// Make server respond so URL1 becomes committed. // Make server respond so URL1 becomes committed.
[self setServerPaused:NO]; [self setServerPaused:NO];
[ChromeEarlGrey waitForWebViewContainingText:kTestPage1]; if (base::FeatureList::IsEnabled(web::features::kWebFrameMessaging)) {
[[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] // With frame messaging, only one back is executed. This is the expected
assertWithMatcher:grey_notNil()]; // behavior.
[ChromeEarlGrey waitForWebViewContainingText:kTestPage2];
[[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())]
assertWithMatcher:grey_notNil()];
} else {
// TODO(crbug.com/866406): fix the test to have documented behavior.
[ChromeEarlGrey waitForWebViewContainingText:kTestPage1];
[[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())]
assertWithMatcher:grey_notNil()];
}
} }
#pragma mark - #pragma mark -
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "ios/web/public/test/fakes/fake_web_frame.h" #include "ios/web/public/test/fakes/fake_web_frame.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/json/json_writer.h"
#include "base/values.h"
namespace web { namespace web {
FakeWebFrame::FakeWebFrame(const std::string& frame_id, FakeWebFrame::FakeWebFrame(const std::string& frame_id,
...@@ -32,6 +34,18 @@ bool FakeWebFrame::CanCallJavaScriptFunction() const { ...@@ -32,6 +34,18 @@ bool FakeWebFrame::CanCallJavaScriptFunction() const {
bool FakeWebFrame::CallJavaScriptFunction( bool FakeWebFrame::CallJavaScriptFunction(
const std::string& name, const std::string& name,
const std::vector<base::Value>& parameters) { const std::vector<base::Value>& parameters) {
last_javascript_call_ = std::string("__gCrWeb." + name + "(");
bool first = true;
for (auto& param : parameters) {
if (!first) {
last_javascript_call_ += ", ";
}
first = false;
std::string paramString;
base::JSONWriter::Write(param, &paramString);
last_javascript_call_ += paramString;
}
last_javascript_call_ += ");";
return false; return false;
} }
...@@ -40,7 +54,7 @@ bool FakeWebFrame::CallJavaScriptFunction( ...@@ -40,7 +54,7 @@ bool FakeWebFrame::CallJavaScriptFunction(
const std::vector<base::Value>& parameters, const std::vector<base::Value>& parameters,
base::OnceCallback<void(const base::Value*)> callback, base::OnceCallback<void(const base::Value*)> callback,
base::TimeDelta timeout) { base::TimeDelta timeout) {
return false; return CallJavaScriptFunction(name, parameters);
} }
} // namespace web } // namespace web
...@@ -31,6 +31,7 @@ class FakeWebFrame : public WebFrame { ...@@ -31,6 +31,7 @@ class FakeWebFrame : public WebFrame {
const std::vector<base::Value>& parameters, const std::vector<base::Value>& parameters,
base::OnceCallback<void(const base::Value*)> callback, base::OnceCallback<void(const base::Value*)> callback,
base::TimeDelta timeout) override; base::TimeDelta timeout) override;
std::string last_javascript_call() { return last_javascript_call_; }
private: private:
// The frame identifier which uniquely identifies this frame across the // The frame identifier which uniquely identifies this frame across the
...@@ -40,6 +41,8 @@ class FakeWebFrame : public WebFrame { ...@@ -40,6 +41,8 @@ class FakeWebFrame : public WebFrame {
bool is_main_frame_ = false; bool is_main_frame_ = false;
// The security origin associated with this frame. // The security origin associated with this frame.
GURL security_origin_; GURL security_origin_;
// The last Javascript script that was called, converted as a string.
std::string last_javascript_call_;
}; };
} // namespace web } // namespace web
......
...@@ -30,7 +30,6 @@ NSString* const kTestFormName = @"FormName"; ...@@ -30,7 +30,6 @@ NSString* const kTestFormName = @"FormName";
NSString* const kTestFormID = @"FormID"; NSString* const kTestFormID = @"FormID";
NSString* const kTestFieldName = @"FieldName"; NSString* const kTestFieldName = @"FieldName";
NSString* const kTestFieldID = @"FieldID"; NSString* const kTestFieldID = @"FieldID";
NSString* const kTestFrameID = @"FrameID";
NSString* const kTestFieldValue = @"FieldValue"; NSString* const kTestFieldValue = @"FieldValue";
NSString* const kTestSubmitID = @"SubmitID"; NSString* const kTestSubmitID = @"SubmitID";
NSString* const kTestFormHtml = NSString* const kTestFormHtml =
...@@ -223,7 +222,7 @@ TEST_F(WebViewAutofillTest, TestSuggestionFetchFillClear) { ...@@ -223,7 +222,7 @@ TEST_F(WebViewAutofillTest, TestSuggestionFetchFillClear) {
ASSERT_NSEQ(nil, filled_error); ASSERT_NSEQ(nil, filled_error);
[autofill_controller_ clearFormWithName:kTestFormName [autofill_controller_ clearFormWithName:kTestFormName
fieldIdentifier:kTestFieldID fieldIdentifier:kTestFieldID
frameID:kTestFrameID frameID:GetMainFrameId()
completionHandler:nil]; completionHandler:nil];
NSString* cleared_script = [NSString NSString* cleared_script = [NSString
stringWithFormat:@"document.getElementById('%@').value", kTestFieldID]; stringWithFormat:@"document.getElementById('%@').value", kTestFieldID];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment