Commit 8928aec1 authored by tommycli@chromium.org's avatar tommycli@chromium.org

Blink Plugins: Remove Shadow DOM plugin placeholder tests.

This is a subset of https://codereview.chromium.org/1313763002/.

The tests have to be removed in a separate patch to unblock the Chromium-side
patch: https://codereview.chromium.org/1314643002/.

BUG=524115

Review URL: https://codereview.chromium.org/1303233007

git-svn-id: svn://svn.chromium.org/blink/trunk@201270 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 1cc37cfd
......@@ -16,13 +16,7 @@ onload = function() {
document.write("PASS");
}
</script>
</haed>
</head>
<body>
<div id="div1"></div>
<embed type="application/x-fake-plugin"</embed>
<script>
var embed = document.querySelector("embed");
if (window.internals)
internals.forcePluginPlaceholder(embed, {});
</script>
</body>
Checks that the plugin placeholder close button works as expected.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS closeButton1.style.display is 'none'
PASS closeButton2.style.display is not 'none'
PASS plugin2.style.display is 'none'
PASS closeButton3.style.display is not 'none'
PASS ancestor3.style.display is 'none'
PASS closeButton4.style.display is not 'none'
PASS document.getElementById('ancestor4a').style.display is not 'none'
PASS document.getElementById('ancestor4b').style.display is not 'none'
PASS document.getElementById('ancestor4c').style.display is not 'none'
PASS document.getElementById('ancestor4d').style.display is not 'none'
PASS document.getElementById('ancestor4e').style.display is not 'none'
PASS closeButton5.style.display is not 'none'
PASS document.getElementById('ancestor5').style.display is not 'none'
PASS closeButton6.style.display is not 'none'
PASS document.getElementById('ancestor6').style.display is 'none'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<div id="description"></div>
<div id="console"></div>
<object id="plugin1" type="application/x-fake-plugin"></object>
<object id="plugin2" type="application/x-fake-plugin"></object>
<div id="ancestor3" style="width: 400px; height: 300px">
<div>
<object id="plugin3" type="application/x-fake-plugin" width="400" height="300"></object>
</div>
</div>
<!--
None of these ancestors should be hidden.
ancestor4a is not explicitly sized.
ancestor4b is explicitly sized, but only in one dimension.
ancestor4c is explicitly sized, but not in the element's inline style.
ancestor4d is explicitly sized to match, but not in pixels.
ancestor4e is explicitly sized, but does not match the plugin's attributes.
-->
<style>
#ancestor4c { width: 400px; height: 300px; }
</style>
<div id="ancestor4a">
<div id="ancestor4b" style="width: 400px">
<div id="ancestor4c">
<div id="ancestor4d" style="font-size: 100px; width: 4em; height: 3em">
<div id="ancestor4e" style="width: 300px; height: 400px">
<object id="plugin4" type="application/x-fake-plugin" width="400" height="300"></object>
</div>
</div>
</div>
</div>
</div>
<!-- The plugin's size is 300x150, but it was not explicitly specified in the presentation attributes. -->
<div id="ancestor5" style="width: 300px; height: 150px">
<object id="plugin5" type="application/x-fake-plugin"></object>
</div>
<div id="ancestor6" style="width: 400px; height: 300px">
<object id="plugin6" type="application/x-fake-plugin" width=" 400 px " height="300px"></object>
</div>
<script>
description("Checks that the plugin placeholder close button works as expected.");
// Non-closeable plugins should have no displayed close button.
var plugin1 = document.getElementById("plugin1");
internals.forcePluginPlaceholder(plugin1, { closeable: false });
var closeButton1 = internals.youngestShadowRoot(plugin1).querySelector("#plugin-placeholder-close-button");
shouldBe("closeButton1.style.display", "'none'");
// After a plugin is closed, it should have "display: none".
var plugin2 = document.getElementById("plugin2");
internals.forcePluginPlaceholder(plugin2, { closeable: true });
var closeButton2 = internals.youngestShadowRoot(plugin2).querySelector("#plugin-placeholder-close-button");
shouldNotBe("closeButton2.style.display", "'none'");
closeButton2.click();
shouldBe("plugin2.style.display", "'none'");
// If the plugin has an ancestor sized to match with inline style, the ancestor should also be hidden.
var plugin3 = document.getElementById("plugin3");
internals.forcePluginPlaceholder(plugin3, { closeable: true });
var closeButton3 = internals.youngestShadowRoot(plugin3).querySelector("#plugin-placeholder-close-button");
shouldNotBe("closeButton3.style.display", "'none'");
closeButton3.click();
var ancestor3 = document.getElementById("ancestor3");
shouldBe("ancestor3.style.display", "'none'");
// If the plugin has ancestors that don't meet this heuristic, they should be left alone.
var plugin4 = document.getElementById("plugin4");
internals.forcePluginPlaceholder(plugin4, { closeable: true });
var closeButton4 = internals.youngestShadowRoot(plugin4).querySelector("#plugin-placeholder-close-button");
shouldNotBe("closeButton4.style.display", "'none'");
closeButton4.click();
shouldNotBe("document.getElementById('ancestor4a').style.display", "'none'");
shouldNotBe("document.getElementById('ancestor4b').style.display", "'none'");
shouldNotBe("document.getElementById('ancestor4c').style.display", "'none'");
shouldNotBe("document.getElementById('ancestor4d').style.display", "'none'");
shouldNotBe("document.getElementById('ancestor4e').style.display", "'none'");
// Plugins with no explicit (presentation attribute) size should not hide ancestors.
var plugin5 = document.getElementById("plugin5");
internals.forcePluginPlaceholder(plugin5, { closeable: true });
var closeButton5 = internals.youngestShadowRoot(plugin5).querySelector("#plugin-placeholder-close-button");
shouldNotBe("closeButton5.style.display", "'none'");
closeButton5.click();
shouldNotBe("document.getElementById('ancestor5').style.display", "'none'");
// This should work even if the presentation attribute has spacing and "px".
var plugin6 = document.getElementById("plugin6");
internals.forcePluginPlaceholder(plugin6, { closeable: true });
var closeButton6 = internals.youngestShadowRoot(plugin6).querySelector("#plugin-placeholder-close-button");
shouldNotBe("closeButton6.style.display", "'none'");
closeButton6.click();
shouldBe("document.getElementById('ancestor6').style.display", "'none'");
</script>
<!DOCTYPE html>
<link rel="stylesheet" href="plugin-placeholder.css">
<div class="plugin">
<div class="plugin-placeholder">
<div class="plugin-placeholder-content">
<div class="plugin-placeholder-message">
This box should be styled despite CSP.
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<!-- Forbid inline style. -->
<meta http-equiv="Content-Security-Policy" content="style-src 'none'">
<!-- The message inserted below should be shown with some suitable style. -->
<embed type="application/x-fake-plugin"></embed>
<script>
var plugin = document.querySelector("embed");
internals.forcePluginPlaceholder(plugin, { message: "This box should be styled despite CSP." });
</script>
<!DOCTYPE html>
<style>
div { margin: 10px; width: 300px; height: 150px; background: green; }
</style>
<div></div>
<div></div>
<div></div>
<!DOCTYPE html>
<style>
div { margin: 10px; width: 300px; height: 150px; background: green; }
</style>
<div style="width: 200px"></div>
<div style="height: 100px"></div>
<div style="width: 200px; height: 100px"></div>
<!DOCTYPE html>
<style>
applet, embed, object { display: block; margin: 10px; }
</style>
<!-- These should appear as green blocks of various sizes (200x150, 300x100, 200x100). -->
<applet code="DoesNotExist.class" width="200"></applet>
<embed type="application/x-fake-plugin" height="100"></embed>
<object type="application/x-fake-plugin" width="200" height="100"></object>
<template id="placeholder-template">
<style>
:host { overflow: hidden }
div { margin: 0; padding: 0; width: 100%; height: 100%; background-color: green; }
</style>
<div></div>
</template>
<script>
var templateContent = document.getElementById('placeholder-template').content;
Array.prototype.forEach.call(document.querySelectorAll("applet, embed, object"), function(plugin) {
internals.forcePluginPlaceholder(plugin, templateContent);
});
</script>
Ensures that elements within a plugin placeholder can be keyboard focused.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS document.activeElement is input1
PASS shadowRoot1.activeElement is null
PASS document.activeElement is plugin1
PASS shadowRoot1.activeElement is non-null.
PASS document.activeElement is input1
PASS shadowRoot1.activeElement is null
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<div id="description"></div>
<div id="console"></div>
<input id="input1">
<object id="plugin1" type="application/x-fake-plugin"></object>
<script>
description('Ensures that elements within a plugin placeholder can be keyboard focused.');
// Close buttons are focusable, so we expect focus to move into and out of the placeholder.
var input1 = document.getElementById("input1");
var plugin1 = document.getElementById("plugin1");
internals.forcePluginPlaceholder(plugin1, { closeable: true });
var shadowRoot1 = internals.youngestShadowRoot(plugin1);
input1.focus();
shouldBe("document.activeElement", "input1");
shouldBeNull("shadowRoot1.activeElement");
eventSender.keyDown("\t");
shouldBe("document.activeElement", "plugin1");
shouldBeNonNull("shadowRoot1.activeElement");
eventSender.keyDown("\t", ["shiftKey"]);
shouldBe("document.activeElement", "input1");
shouldBeNull("shadowRoot1.activeElement");
document.activeElement.blur();
</script>
<!DOCTYPE html>
<link rel="stylesheet" href="plugin-placeholder.css">
<div class="plugin">
<div class="plugin-placeholder">
<div class="plugin-placeholder-content">
<div class="plugin-placeholder-message">
This test fails if this text is red, underlined, or uppercase.
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<!-- These properties should not propagate into the placeholder. -->
<style>
body {
color: red;
text-decoration: underline;
text-transform: uppercase;
}
</style>
<!-- The message inserted below should be shown with some suitable style. -->
<embed type="application/x-fake-plugin"></embed>
<script>
var plugin = document.querySelector("embed");
internals.forcePluginPlaceholder(plugin, { message: "This test fails if this text is red, underlined, or uppercase." });
</script>
Ensures that the private PluginPlaceholderElement interface is not exposed.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS window.PluginPlaceholderElement is undefined.
PASS PluginPlaceholderElement threw exception ReferenceError: PluginPlaceholderElement is not defined.
PASS PluginPlaceholderElement.prototype threw exception ReferenceError: PluginPlaceholderElement is not defined.
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<script>
description('Ensures that the private PluginPlaceholderElement interface is not exposed.');
shouldBeUndefined('window.PluginPlaceholderElement');
shouldThrow('PluginPlaceholderElement');
shouldThrow('PluginPlaceholderElement.prototype');
</script>
<!DOCTYPE html>
<link rel="stylesheet" href="plugin-placeholder.css">
<div class="plugin">
<div class="plugin-placeholder">
<div class="plugin-placeholder-content">
<div class="plugin-placeholder-message">
Sorry, but your plugin couldn't be loaded.
</div>
</div>
</div>
</div>
<div class="plugin">
<div class="plugin-placeholder">
<div class="plugin-placeholder-content">
<div class="plugin-placeholder-message">
Sorry, but your plugin couldn't be loaded.
</div>
<button>Close</button>
</div>
</div>
</div>
<!DOCTYPE html>
<style>
applet, embed, object { display: block; }
</style>
<!-- The placeholders inserted below should be shown with some suitable style. -->
<object id="plugin1" type="application/x-fake-plugin"></object>
<object id="plugin2" type="application/x-fake-plugin"></object>
<script>
internals.forcePluginPlaceholder(document.getElementById('plugin1'), { message: "Sorry, but your plugin couldn't be loaded." });
internals.forcePluginPlaceholder(document.getElementById('plugin2'), { message: "Sorry, but your plugin couldn't be loaded.", closeable: true });
</script>
.plugin {
display: block;
width: 300px;
height: 150px;
}
.plugin-placeholder {
all: initial;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: center;
background-color: gray;
font: 12px -webkit-control;
}
.plugin-placeholder-content {
text-align: center;
margin: auto;
}
<!DOCTYPE html>
<style>
applet, embed, object { display: block; margin: 10px; }
</style>
<!-- These should all appear as 300x150 green blocks. -->
<applet code="DoesNotExist.class"></applet>
<embed type="application/x-fake-plugin"></embed>
<object type="application/x-fake-plugin"></object>
<template id="placeholder-template">
<style>
:host { overflow: hidden }
div { margin: 0; padding: 0; width: 100%; height: 100%; background-color: green; }
</style>
<div></div>
</template>
<script>
var templateContent = document.getElementById('placeholder-template').content;
Array.prototype.forEach.call(document.querySelectorAll("applet, embed, object"), function(plugin) {
internals.forcePluginPlaceholder(plugin, templateContent);
});
</script>
// Copyright 2014 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 "config.h"
#include "web/PluginPlaceholderImpl.h"
#include "core/CSSPropertyNames.h"
#include "core/CSSValueKeywords.h"
#include "core/HTMLNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSValue.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/TagCollection.h"
#include "core/testing/DummyPageHolder.h"
#include "public/web/WebPluginPlaceholder.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using testing::Return;
namespace blink {
namespace {
using HTMLNames::scriptTag;
class MockWebPluginPlaceholder : public WebPluginPlaceholder {
public:
static PassOwnPtr<MockWebPluginPlaceholder> create() { return adoptPtr(new MockWebPluginPlaceholder); }
~MockWebPluginPlaceholder() override { }
MOCK_CONST_METHOD0(message, WebString());
MOCK_CONST_METHOD0(isCloseable, bool());
private:
MockWebPluginPlaceholder()
{
ON_CALL(*this, message()).WillByDefault(Return(WebString()));
}
};
// Fixture which creates a dummy context for running these this test.
// Notably creates a document fragment, since Document returns nothing for
// textContent, and mocks out the underlying WebPluginPlaceholder.
class PluginPlaceholderImplTest : public ::testing::Test {
protected:
PluginPlaceholderImplTest()
: m_pageHolder(DummyPageHolder::create())
, m_documentFragment(m_pageHolder->document().createDocumentFragment())
{
OwnPtr<MockWebPluginPlaceholder> webPluginPlaceholder = MockWebPluginPlaceholder::create();
m_webPluginPlaceholder = webPluginPlaceholder.get();
m_pluginPlaceholderImpl = PluginPlaceholderImpl::create(webPluginPlaceholder.release(), document());
}
Document& document() { return m_pageHolder->document(); }
DocumentFragment& documentFragment() { return *m_documentFragment; }
MockWebPluginPlaceholder& webPluginPlaceholder() { return *m_webPluginPlaceholder; }
PluginPlaceholder& pluginPlaceholder() { return *m_pluginPlaceholderImpl; }
private:
OwnPtr<DummyPageHolder> m_pageHolder;
RefPtrWillBePersistent<DocumentFragment> m_documentFragment;
MockWebPluginPlaceholder* m_webPluginPlaceholder; // owned by PluginPlaceholderImpl
OwnPtrWillBePersistent<PluginPlaceholderImpl> m_pluginPlaceholderImpl;
};
TEST_F(PluginPlaceholderImplTest, MessageIsShown)
{
String message = "Hello world!";
EXPECT_CALL(webPluginPlaceholder(), message()).WillOnce(Return(message));
pluginPlaceholder().loadIntoContainer(documentFragment());
EXPECT_TRUE(documentFragment().textContent().contains(message));
}
TEST_F(PluginPlaceholderImplTest, MessageDoesNotRunScripts)
{
String message = "<script>console.log('this should not run');</script>";
EXPECT_CALL(webPluginPlaceholder(), message()).WillOnce(Return(message));
pluginPlaceholder().loadIntoContainer(documentFragment());
EXPECT_TRUE(documentFragment().textContent().contains(message));
EXPECT_TRUE(documentFragment().getElementsByTagName(scriptTag.localName())->isEmpty());
}
TEST_F(PluginPlaceholderImplTest, MessageDoesNotAcceptElements)
{
String message = "<h1 id='sentinel'>sentinel</h1>";
EXPECT_CALL(webPluginPlaceholder(), message()).WillOnce(Return(message));
pluginPlaceholder().loadIntoContainer(documentFragment());
EXPECT_TRUE(documentFragment().textContent().contains(message));
EXPECT_FALSE(documentFragment().getElementById("sentinel"));
}
bool isHiddenWithInlineStyle(Element* element)
{
if (!element->inlineStyle())
return false;
RefPtrWillBeRawPtr<CSSValue> value = element->inlineStyle()->getPropertyCSSValue(CSSPropertyDisplay);
return value && value->isPrimitiveValue() && toCSSPrimitiveValue(value.get())->getValueID() == CSSValueNone;
}
TEST_F(PluginPlaceholderImplTest, Closeable)
{
// The closing functionality of PluginPlaceholderElement is tested in
// LayoutTests/fast/plugins. This test only needs to ensure that the
// boolean in WebPluginPlaceholder is respected.
EXPECT_CALL(webPluginPlaceholder(), isCloseable()).WillOnce(Return(true));
pluginPlaceholder().loadIntoContainer(documentFragment());
RefPtrWillBeRawPtr<Element> closeButton = documentFragment().getElementById("plugin-placeholder-close-button");
ASSERT_NE(nullptr, closeButton);
EXPECT_FALSE(isHiddenWithInlineStyle(closeButton.get()));
}
TEST_F(PluginPlaceholderImplTest, NotCloseable)
{
EXPECT_CALL(webPluginPlaceholder(), isCloseable()).WillOnce(Return(false));
pluginPlaceholder().loadIntoContainer(documentFragment());
RefPtrWillBeRawPtr<Element> closeButton = documentFragment().getElementById("plugin-placeholder-close-button");
EXPECT_NE(nullptr, closeButton);
EXPECT_TRUE(isHiddenWithInlineStyle(closeButton.get()));
}
} // namespace
} // namespace blink
......@@ -34,11 +34,8 @@
#include "core/loader/FrameLoader.h"
#include "platform/weborigin/KURL.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebPluginParams.h"
#include "public/web/WebPluginPlaceholder.h"
#include "public/web/WebSettings.h"
#include "public/web/WebView.h"
#include "web/PluginPlaceholderImpl.h"
#include "web/WebLocalFrameImpl.h"
#include "web/tests/FrameTestHelpers.h"
#include "wtf/text/CString.h"
......@@ -58,7 +55,6 @@ public:
~MockWebFrameClient() override { }
MOCK_METHOD2(userAgentOverride, WebString(WebLocalFrame*, const WebURL&));
MOCK_METHOD2(createPluginPlaceholder, WebPluginPlaceholder*(WebLocalFrame*, const WebPluginParams&));
};
class FrameLoaderClientImplTest : public ::testing::Test {
......@@ -116,34 +112,5 @@ TEST_F(FrameLoaderClientImplTest, UserAgentOverride)
EXPECT_TRUE(defaultUserAgent.equals(userAgent()));
}
TEST_F(FrameLoaderClientImplTest, CreatePluginPlaceholderForwardsToWebFrameClient)
{
KURL url(ParsedURLString, "http://www.example.com/plugin.swf");
Vector<String> paramNames(1, "param");
Vector<String> paramValues(1, "value");
String mimeType = "application/x-shockwave-flash";
bool loadManually = false;
// Test with a valid WebPluginPlaceholder.
{
WebPluginPlaceholder* webPluginPlaceholder = new WebPluginPlaceholder;
EXPECT_CALL(webFrameClient(), createPluginPlaceholder(mainFrame(), _))
.WillOnce(Return(webPluginPlaceholder));
OwnPtrWillBeRawPtr<PluginPlaceholder> pluginPlaceholder = frameLoaderClient().createPluginPlaceholder(
document(), url, paramNames, paramValues, mimeType, loadManually);
ASSERT_TRUE(pluginPlaceholder);
EXPECT_EQ(webPluginPlaceholder, static_cast<PluginPlaceholderImpl*>(pluginPlaceholder.get())->webPluginPlaceholder());
}
// Test with no WebPluginPlaceholder.
{
EXPECT_CALL(webFrameClient(), createPluginPlaceholder(mainFrame(), _))
.WillOnce(Return(nullptr));
OwnPtrWillBeRawPtr<PluginPlaceholder> pluginPlaceholder = frameLoaderClient().createPluginPlaceholder(
document(), url, paramNames, paramValues, mimeType, loadManually);
ASSERT_FALSE(pluginPlaceholder);
}
}
} // namespace
} // namespace blink
......@@ -259,7 +259,6 @@
'ExternalPopupMenuTest.cpp',
'LinkHighlightImplTest.cpp',
'PageOverlayTest.cpp',
'PluginPlaceholderImplTest.cpp',
'WebDragDataTest.cpp',
'WebEmbeddedWorkerImplTest.cpp',
'WebNodeTest.cpp',
......
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