blob: 7793fe1aa42e1e84b9d2f8a44151470a4c2c8666 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/web/js_messaging/java_script_feature_manager.h"
#import <WebKit/WebKit.h>
#include "base/ios/ios_util.h"
#import "ios/web/public/js_messaging/java_script_feature.h"
#import "ios/web/public/test/fakes/fake_web_client.h"
#include "ios/web/public/test/web_test.h"
#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
#import "testing/gtest_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// A test fixture for testing JavaScriptFeatureManager.
class JavaScriptFeatureManagerTest : public web::WebTest {
protected:
JavaScriptFeatureManagerTest()
: web::WebTest(std::make_unique<web::FakeWebClient>()) {}
web::JavaScriptFeatureManager* GetJavaScriptFeatureManager() {
web::JavaScriptFeatureManager* java_script_feature_manager =
web::JavaScriptFeatureManager::FromBrowserState(GetBrowserState());
return java_script_feature_manager;
}
WKUserContentController* GetUserContentController() {
return web::WKWebViewConfigurationProvider::FromBrowserState(
GetBrowserState())
.GetWebViewConfiguration()
.userContentController;
}
void SetUp() override {
web::WebTest::SetUp();
[GetUserContentController() removeAllUserScripts];
}
};
// Tests that JavaScriptFeatureManager adds base shared user scripts.
TEST_F(JavaScriptFeatureManagerTest, Configure) {
ASSERT_TRUE(GetJavaScriptFeatureManager());
ASSERT_EQ(0ul, [GetUserContentController().userScripts count]);
GetJavaScriptFeatureManager()->ConfigureFeatures({});
if (base::ios::IsRunningOnIOS14OrLater()) {
EXPECT_EQ(6ul, [GetUserContentController().userScripts count]);
} else {
EXPECT_EQ(3ul, [GetUserContentController().userScripts count]);
}
}
// Tests that JavaScriptFeatureManager adds a JavaScriptFeature for all frames
// at document start time for the page content world.
TEST_F(JavaScriptFeatureManagerTest, AllFramesStartFeature) {
ASSERT_TRUE(GetJavaScriptFeatureManager());
std::vector<const web::JavaScriptFeature::FeatureScript> feature_scripts = {
web::JavaScriptFeature::FeatureScript::CreateWithFilename(
"java_script_feature_test_inject_once_js",
web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart,
web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames)};
std::unique_ptr<web::JavaScriptFeature> feature =
std::make_unique<web::JavaScriptFeature>(
web::JavaScriptFeature::ContentWorld::kPageContentWorld,
feature_scripts);
GetJavaScriptFeatureManager()->ConfigureFeatures({feature.get()});
if (base::ios::IsRunningOnIOS14OrLater()) {
EXPECT_EQ(7ul, [GetUserContentController().userScripts count]);
} else {
EXPECT_EQ(4ul, [GetUserContentController().userScripts count]);
}
WKUserScript* user_script =
[GetUserContentController().userScripts lastObject];
EXPECT_TRUE(
[user_script.source containsString:@"__gCrWeb.javaScriptFeatureTest"]);
EXPECT_EQ(WKUserScriptInjectionTimeAtDocumentStart,
user_script.injectionTime);
EXPECT_EQ(NO, user_script.forMainFrameOnly);
}
// Tests that JavaScriptFeatureManager adds a JavaScriptFeature for all frames
// at document end time for any content world.
TEST_F(JavaScriptFeatureManagerTest, MainFrameEndFeature) {
ASSERT_TRUE(GetJavaScriptFeatureManager());
std::vector<const web::JavaScriptFeature::FeatureScript> feature_scripts = {
web::JavaScriptFeature::FeatureScript::CreateWithFilename(
"java_script_feature_test_inject_once_js",
web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd,
web::JavaScriptFeature::FeatureScript::TargetFrames::kMainFrame)};
std::unique_ptr<web::JavaScriptFeature> feature =
std::make_unique<web::JavaScriptFeature>(
web::JavaScriptFeature::ContentWorld::kAnyContentWorld,
feature_scripts);
GetJavaScriptFeatureManager()->ConfigureFeatures({feature.get()});
if (base::ios::IsRunningOnIOS14OrLater()) {
EXPECT_EQ(7ul, [GetUserContentController().userScripts count]);
} else {
EXPECT_EQ(4ul, [GetUserContentController().userScripts count]);
}
WKUserScript* user_script =
[GetUserContentController().userScripts lastObject];
EXPECT_TRUE(
[user_script.source containsString:@"__gCrWeb.javaScriptFeatureTest"]);
EXPECT_EQ(WKUserScriptInjectionTimeAtDocumentEnd, user_script.injectionTime);
EXPECT_EQ(YES, user_script.forMainFrameOnly);
}
// Tests that JavaScriptFeatureManager adds a JavaScriptFeature for all frames
// at document end time for an isolated world.
TEST_F(JavaScriptFeatureManagerTest, MainFrameEndFeatureIsolatedWorld) {
// Using ContentWorld::kIsolatedWorldOnly on older versions of iOS will
// trigger a DCHECK, so return early before that happens.
if (!base::ios::IsRunningOnIOS14OrLater()) {
return;
}
ASSERT_TRUE(GetJavaScriptFeatureManager());
std::vector<const web::JavaScriptFeature::FeatureScript> feature_scripts = {
web::JavaScriptFeature::FeatureScript::CreateWithFilename(
"java_script_feature_test_inject_once_js",
web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd,
web::JavaScriptFeature::FeatureScript::TargetFrames::kMainFrame)};
std::unique_ptr<web::JavaScriptFeature> feature =
std::make_unique<web::JavaScriptFeature>(
web::JavaScriptFeature::ContentWorld::kIsolatedWorldOnly,
feature_scripts);
GetJavaScriptFeatureManager()->ConfigureFeatures({feature.get()});
EXPECT_EQ(7ul, [GetUserContentController().userScripts count]);
WKUserScript* user_script =
[GetUserContentController().userScripts lastObject];
EXPECT_TRUE(
[user_script.source containsString:@"__gCrWeb.javaScriptFeatureTest"]);
EXPECT_EQ(WKUserScriptInjectionTimeAtDocumentEnd, user_script.injectionTime);
EXPECT_EQ(YES, user_script.forMainFrameOnly);
}