blob: c2d802c3b7cb695512bfba0ce25b50510b43c2c9 [file] [log] [blame]
// Copyright 2019 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.
#include "base/bind.h"
#import "base/ios/ios_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "ios/testing/embedded_test_server_handlers.h"
#import "ios/web/js_messaging/java_script_feature_util_impl.h"
#import "ios/web/public/test/fakes/fake_web_client.h"
#import "ios/web/public/test/navigation_test_util.h"
#import "ios/web/public/test/web_test_with_web_state.h"
#import "ios/web/public/test/web_view_content_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
const char kPluginNotSupportedText[] =
"hahaha, your plugin is not supported :D";
const char16_t kPluginNotSupportedText16[] =
u"hahaha, your plugin is not supported :D";
}
namespace web {
// Tests that web page shows a placeholder for unsupported plugins.
class PluginPlaceholderTest : public WebTestWithWebState {
protected:
PluginPlaceholderTest()
: WebTestWithWebState(std::make_unique<FakeWebClient>()) {
FakeWebClient* web_client = static_cast<FakeWebClient*>(GetWebClient());
web_client->SetPluginNotSupportedText(kPluginNotSupportedText16);
}
// Sets up |server_| with |html| as response content.
[[nodiscard]] bool SetUpServer(const std::string& html) {
server_.RegisterDefaultHandler(
base::BindRepeating(&testing::HandlePageWithHtml, html));
return server_.Start();
}
net::test_server::EmbeddedTestServer server_;
};
// Tests that a large <applet> with text fallback is untouched.
TEST_F(PluginPlaceholderTest, AppletFallback) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Applet, text fallback";
const char kFallbackText[] = "Java? On iOS? C'mon.";
const std::string page =
base::StringPrintf("<html><body width='800' height='600'>"
"<p>%s</p>"
"<applet code='Some.class' width='550' height='550'>"
" <p>%s</p>"
"</applet>"
"</body></html>",
kPageDescription, kFallbackText);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that placeholder image is not displayed.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewContainingText(web_state(), kFallbackText));
EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
kPluginNotSupportedText));
}
// Tests placeholder for a large <applet> with no fallback.
TEST_F(PluginPlaceholderTest, AppletOnly) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Applet, no fallback";
const std::string page =
base::StringPrintf("<html><body width='800' height='600'>"
"<p>%s</p>"
"<applet code='Some.class' width='550' height='550'>"
"</applet>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that plugin object is replaced with placeholder image.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewContainingElement(
web_state(),
[ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
}
// Tests placeholder for a large <object> with a flash embed fallback.
TEST_F(PluginPlaceholderTest, ObjectFlashEmbedFallback) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Object, embed fallback";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0' width='550' height='550'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' type='application/x-shockwave-flash' "
"width='550' height='550'>"
"</object>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that plugin object is replaced with placeholder image.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewContainingElement(
web_state(),
[ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
}
// Tests that a large <object> with an embed fallback of unspecified type is
// untouched.
TEST_F(PluginPlaceholderTest, ObjectUndefinedEmbedFallback) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Object, embed fallback";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0' width='550' height='550'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' width='550' height='550'>"
"</object>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that placeholder image is not displayed.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
kPluginNotSupportedText));
}
// Tests that a large <object> with text fallback is untouched.
TEST_F(PluginPlaceholderTest, ObjectFallback) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Object, text fallback";
const char kFallbackText[] = "You don't have Flash. Tough luck!";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
"<object type='application/x-shockwave-flash' data='some.sfw'"
" width='550' height='550'>"
" <param name='movie' value='some.swf'>"
" <p>%s</p>"
"</object>"
"</body></html>",
kPageDescription, kFallbackText);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that placeholder image is not displayed.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewContainingText(web_state(), kFallbackText));
EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
kPluginNotSupportedText));
}
// Tests placeholder for a large <object> with no fallback.
TEST_F(PluginPlaceholderTest, ObjectOnly) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Object, no fallback";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
"<object type='application/x-shockwave-flash' data='some.swf'"
" width='550' height='550'>"
"</object>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that plugin object is replaced with placeholder image.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewContainingElement(
web_state(),
[ElementSelector selectorWithCSSSelector:"img[src*='data']"]));
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPluginNotSupportedText));
}
// Tests that a large png <object> is untouched.
TEST_F(PluginPlaceholderTest, PNGObject) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "PNG object";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
"<object data='foo.png' type='image/png' width='550' height='550'>"
"</object>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that placeholder image is not displayed.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
kPluginNotSupportedText));
}
// Test that non-major plugins (e.g., top/side ads) don't get placeholders.
TEST_F(PluginPlaceholderTest, SmallFlash) {
// Plugin Placeholder is no longer used as of iOS 14.5 as <applet> support is
// completely removed.
// TODO(crbug.com/1218221): Remove feature once app is iOS 14.5+.
if (base::ios::IsRunningOnOrLater(14, 5, 0)) {
return;
}
const char kPageDescription[] = "Flash ads";
const std::string page = base::StringPrintf(
"<html><body width='800' height='600'>"
"<p>%s</p>"
// 160x600 "skyscraper"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0' width='160' height='600'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' width='160' height='600'>"
"</object>"
// 468x60 "full banner"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0' width='468' height='60'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' width='468' height='60'>"
"</object>"
// 728x90 "leaderboard"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0' width='728' height='90'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' width='728' height='90'>"
"</object>"
"</body></html>",
kPageDescription);
ASSERT_TRUE(SetUpServer(page));
test::LoadUrl(web_state(), server_.GetURL("/"));
ASSERT_TRUE(WaitUntilLoaded());
// Verify that placeholder image is not displayed.
EXPECT_TRUE(
test::WaitForWebViewContainingText(web_state(), kPageDescription));
EXPECT_TRUE(test::WaitForWebViewNotContainingElement(
web_state(), [ElementSelector selectorWithCSSSelector:"img"]));
EXPECT_TRUE(test::WaitForWebViewNotContainingText(web_state(),
kPluginNotSupportedText));
}
} // namespace web