diff --git a/DEPS b/DEPS index 74f3749..1929245 100644 --- a/DEPS +++ b/DEPS
@@ -74,7 +74,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'a0985d960fb7c2010274a0fb4a8aa771ece6dc1f', + 'skia_revision': 'ea6138253bda6edef21c3a51d47f893c79f29ef8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -634,7 +634,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '05591bbeae6592fd924caec8e728a4ea86cbb8c9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '87ed4487e40dad8c0c5d415b95f3c40c5b4d2db4', # commit position 20628 + Var('webrtc_git') + '/src.git' + '@' + 'a9f469b2184dfdb723fc23e90076c37916f08157', # commit position 20628 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java index df7faee..de46dd6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -7,7 +7,6 @@ import android.app.Activity; import android.text.TextUtils; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.browser.ChromeVersionInfo; @@ -78,9 +77,9 @@ // Promo can be shown at most once every 2 Chrome major versions. if (currentMajorVersion < lastPromoMajorVersion + 2) return false; - // Don't show if account list hasn't changed since the last time promo was shown. + // Don't show if no new accounts have been added after the last time promo was shown. Set<String> previousAccountNames = preferenceManager.getSigninPromoLastAccountNames(); - return !ApiCompatibilityUtils.objectEquals(previousAccountNames, accountNames); + return previousAccountNames == null || !previousAccountNames.containsAll(accountNames); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 0fd63f4d..0ca9de58 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -517,7 +517,7 @@ if (dpPerMs > SHEET_SWIPE_MAX_DP_PER_MS) { if (shouldRecordHistogram && !mIsSwipeVelocityRecorded) { - recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Fail", + recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Fail", (int) mLastSheetOpenMicrosPerDp); mIsSwipeVelocityRecorded = true; } @@ -526,7 +526,7 @@ } if (shouldRecordHistogram && !mIsSwipeVelocityRecorded) { - recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Success", + recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Success", (int) mLastSheetOpenMicrosPerDp); mIsSwipeVelocityRecorded = true; } @@ -597,7 +597,7 @@ || reason == StateChangeReason.BACK_PRESS || reason == StateChangeReason.TAP_SCRIM; if (mShouldRecordSwipeVelocity && shouldRecordClose) { - recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.NoNavigation", + recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.NoNavigation", (int) mLastSheetOpenMicrosPerDp); } mShouldRecordSwipeVelocity = false; @@ -624,7 +624,7 @@ */ private void recordVelocityForNavigation() { if (!mShouldRecordSwipeVelocity) return; - recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Navigation", + recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Navigation", (int) mLastSheetOpenMicrosPerDp); mShouldRecordSwipeVelocity = false; }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java index 773944b..bb8b02f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
@@ -22,8 +22,6 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.testing.local.LocalRobolectricTestRunner; -import java.util.Set; - /** Tests for {@link SigninPromoUtil}. */ @RunWith(LocalRobolectricTestRunner.class) @Config(manifest = Config.NONE) @@ -79,18 +77,38 @@ } @Test - public void whenAllConditionsAreMetShouldReturnTrue() { + public void whenNoAccountListStoredShouldReturnTrue() { when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40); + // Old implementation hasn't been storing account list + when(mPreferenceManager.getSigninPromoLastAccountNames()).thenReturn(null); Assert.assertTrue(SigninPromoUtil.shouldLaunchSigninPromo( mPreferenceManager, 42, false, false, ImmutableSet.of("test@gmail.com"))); } @Test + public void whenHasNewAccountShouldReturnTrue() { + when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40); + when(mPreferenceManager.getSigninPromoLastAccountNames()) + .thenReturn(ImmutableSet.of("test@gmail.com")); + Assert.assertTrue(SigninPromoUtil.shouldLaunchSigninPromo(mPreferenceManager, 42, false, + false, ImmutableSet.of("test@gmail.com", "test2@gmail.com"))); + } + + @Test public void whenAccountListUnchangedShouldReturnFalse() { when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40); - Set<String> accountNames = ImmutableSet.of("test@gmail.com"); - when(mPreferenceManager.getSigninPromoLastAccountNames()).thenReturn(accountNames); + when(mPreferenceManager.getSigninPromoLastAccountNames()) + .thenReturn(ImmutableSet.of("test@gmail.com")); Assert.assertFalse(SigninPromoUtil.shouldLaunchSigninPromo( - mPreferenceManager, 42, false, false, accountNames)); + mPreferenceManager, 42, false, false, ImmutableSet.of("test@gmail.com"))); + } + + @Test + public void whenNoNewAccountsShouldReturnFalse() { + when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40); + when(mPreferenceManager.getSigninPromoLastAccountNames()) + .thenReturn(ImmutableSet.of("test@gmail.com", "test2@gmail.com")); + Assert.assertFalse(SigninPromoUtil.shouldLaunchSigninPromo( + mPreferenceManager, 42, false, false, ImmutableSet.of("test2@gmail.com"))); } }
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc index c47f338..ea5cf7b8 100644 --- a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
@@ -7,6 +7,8 @@ #include "base/strings/pattern.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/speech_monitor.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_details.h" @@ -40,6 +42,20 @@ SpeechMonitor speech_monitor_; std::unique_ptr<ui::test::EventGenerator> generator_; + void ActivateSelectToSpeakInWindowBounds(std::string url) { + ui_test_utils::NavigateToURL(browser(), GURL(url)); + gfx::Rect bounds = browser()->window()->GetBounds(); + + // Hold down Search and click a few pixels into the window bounds. + generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */); + generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50); + generator_->PressLeftButton(); + generator_->MoveMouseTo(bounds.x() + bounds.width() - 8, + bounds.y() + bounds.height() - 8); + generator_->ReleaseLeftButton(); + generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */); + } + private: DISALLOW_COPY_AND_ASSIGN(SelectToSpeakTest); }; @@ -59,4 +75,80 @@ base::MatchPattern(speech_monitor_.GetNextUtterance(), "Status tray*")); } +IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SearchLocksToSelectToSpeakMode) { + ui_test_utils::NavigateToURL(browser(), GURL("data:text/html;charset=utf-8," + "<p>This is some text</p>")); + gfx::Rect bounds = browser()->window()->GetBounds(); + + // Hold click Search, then and click a few pixels into the window bounds. + generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */); + generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */); + + for (int i = 0; i < 2; ++i) { + // With the mouse only, have it speak a few times. + generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50); + generator_->PressLeftButton(); + generator_->MoveMouseTo(bounds.x() + bounds.width() - 8, + bounds.y() + bounds.height() - 8); + generator_->ReleaseLeftButton(); + + EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), + "This is some text*")); + } +} + +IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossInlineUrl) { + // Make sure an inline URL is read smoothly. + ActivateSelectToSpeakInWindowBounds( + "data:text/html;charset=utf-8,<p>This is some text <a href=>with a" + " node</a> in the middle"); + // Should combine nodes in a paragraph into one utterance. + // Includes some wildcards between words because there may be extra + // spaces. Spaces are not pronounced, so extra spaces do not impact output. + EXPECT_TRUE( + base::MatchPattern(speech_monitor_.GetNextUtterance(), + "This is some text*with a node*in the middle*")); +} + +IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossMultipleLines) { + // Sentences spanning multiple lines. + ActivateSelectToSpeakInWindowBounds( + "data:text/html;charset=utf-8,<div style=\"width:100px\">This" + " is some text with a node in the middle"); + // Should combine nodes in a paragraph into one utterance. + // Includes some wildcards between words because there may be extra + // spaces, for example at line wraps. Extra wildcards included to + // reduce flakyness in case wrapping is not consistent. + // Spaces are not pronounced, so extra spaces do not impact output. + EXPECT_TRUE( + base::MatchPattern(speech_monitor_.GetNextUtterance(), + "This is some*text*with*a*node*in*the*middle*")); +} + +IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossFormattedText) { + // Bold or formatted text + ActivateSelectToSpeakInWindowBounds( + "data:text/html;charset=utf-8,<p>This is some text <b>with a node" + "</b> in the middle"); + + // Should combine nodes in a paragraph into one utterance. + // Includes some wildcards between words because there may be extra + // spaces. Spaces are not pronounced, so extra spaces do not impact output. + EXPECT_TRUE( + base::MatchPattern(speech_monitor_.GetNextUtterance(), + "This is some text*with a node*in the middle*")); +} + +IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, BreaksAtParagraphBounds) { + ActivateSelectToSpeakInWindowBounds( + "data:text/html;charset=utf-8,<div><p>First paragraph</p>" + "<p>Second paragraph</p></div>"); + + // Should keep each paragraph as its own utterance. + EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), + "First paragraph*")); + EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), + "Second paragraph*")); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.cc b/chrome/browser/chromeos/accessibility/speech_monitor.cc index a0cf87e6..14169e3 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.cc +++ b/chrome/browser/chromeos/accessibility/speech_monitor.cc
@@ -40,6 +40,14 @@ return did_stop_; } +void SpeechMonitor::BlockUntilStop() { + if (!did_stop_) { + loop_runner_ = new content::MessageLoopRunner(); + loop_runner_->Run(); + loop_runner_ = NULL; + } +} + bool SpeechMonitor::SkipChromeVoxMessage(const std::string& message) { while (true) { if (utterance_queue_.empty()) {
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.h b/chrome/browser/chromeos/accessibility/speech_monitor.h index 3512ed9c..6888b8b6 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.h +++ b/chrome/browser/chromeos/accessibility/speech_monitor.h
@@ -32,6 +32,9 @@ // Returns true if StopSpeaking() was called on TtsController. bool DidStop(); + // Blocks until StopSpeaking() is called on TtsController. + void BlockUntilStop(); + private: // TtsPlatformImpl implementation. bool PlatformImplAvailable() override;
diff --git a/docs/accessibility.md b/docs/accessibility.md index eef1344f..869e1d1 100644 --- a/docs/accessibility.md +++ b/docs/accessibility.md
@@ -3,6 +3,10 @@ * [Accessibility Overview](accessibility/overview.md) * [Accessibility Tests](accessibility/tests.md) +## Cross-Platform + +* [Offscreen, Invisible and Size](accessibility/offscreen.md) + ## Chrome OS * [ChromeVox for Developers](accessibility/chromevox.md)
diff --git a/docs/accessibility/offscreen.md b/docs/accessibility/offscreen.md new file mode 100644 index 0000000..8658c7f6 --- /dev/null +++ b/docs/accessibility/offscreen.md
@@ -0,0 +1,145 @@ +# Offscreen, Invisible and Size + +This document explains how Chrome interprets the guidelines to apply the labels +Offscreen and Invisible to nodes, and how the bounding box is calculated. + +## Background + +In general, screen reading tools may be interested in all nodes regardless of +whether they are presented to sighted users, but other Accessibility tools may +care what is visible to sighted users. + +Specifically, tools like Select-to-Speak and Switch Access should not look at +nodes which are “offscreen”, “invisible”, or size=(0,0), as these are not +visible on the screen for mouse interactions. On the other hand, ChromeVox and +other screen readers may care about some of those nodes, which allow developers +to insert buttons visible only to users with a screen reader, or to navigate +below the fold. + +## Offscreen +In Chrome, we define Offscreen as: + +>Any object is offscreen if it is fully clipped or scrolled out of view by any +of its ancestors so that it is not rendered on the screen. + +For example, the staticText node here is offscreen: +```html +<div style="width:0; height; 0; overflow: hidden"> + This text should be marked "offscreen", although its parent is not. +</div> +``` + +As background, [MSDN](https://msdn.microsoft.com/en-us/library/dd373609(VS.85).aspx) +defines Offscreen as an object is not rendered, but not because it was +programatically hidden: + +>The object is clipped or has scrolled out of view, but it is not +programmatically hidden. If the user makes the viewport larger, more of the +object will be visible on the computer screen. + +In Chrome, we interpret this to mean that an object is fully clipped or +scrolled out of view by its parent or ancestors. The main difference is that +we are being explicit that any ancestor clipping a node can make it offscreen, +not just a rootWebArea or scrollable ancestor. + +### Technical Implementation +Offscreen is calculated in [AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc). +In this function, we walk up the accessibility tree adjusting a node's bounding +box to the frame of its ancestors. If the box is clipped because it lies +outside an ancestor's bounds, and that ancestor clips its children (i.e. +overflow:hidden, overflow:scroll, or it is a rootWebArea), offscreen is set to +true. + +## Invisible +A node is marked Invisible in Chrome if it is hidden programatically. In some +cases, invisible nodes are simply excluded from the accessibility tree. Chrome +defines invisible as: + +>Invisible means that a node or its ancestor is explicitly invisible. + +This is the same as the definition from [MSDN](https://msdn.microsoft.com/en-us/library/dd373609(VS.85).aspx): + +>The object is programmatically hidden. + +For example, these nodes are invisible: + +```html +<div style="display:none"> + This text should be marked 'invisible', along with its parent div. +</div> + +<div style="visibility:hidden"> + This text should also be marked 'invisible' along with its parent div. +</div> + +<div style="opacity:0"> + Opactiy zero is also treated as invisible. +</div> +``` + +## Bounding box calculation +A node's bounding box (location and size) are calculated based on its +intrinsic width, height and location, and the sizes of its ancestors. +We calculate size clipped by ancestors by default, but can also expose an +unclipped size through the [automation API](https://developer.chrome.com/extensions/automation). + +The unclipped bounding box is helpful if you want to know the current +coordinates of an element that's scrolled out of view, so you know how +much to scroll to bring it in view. + +The clipped bounding box is helpful if you want to draw a visible bounding +box around the element on the screen. Clipping the bounding box helps +sighted users understand what container the element is in, even if it's +not currently visible. Without clipping you end up with elements floating +outside of windows. + +### Technical implementation +A node's location and size are calculated in[AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc), +and so closely tied to the offscreen calculation. In this function, we walk up +the accessibility tree adjusting a node's bounding box to the frame of its +ancestors. + +In general, this calculation is straight forward. But there are several edge +cases: + +* If a node has no intrinsic size, its size will be taken from the union of +its children. + +```html + <!-- The outer div here has no size, so we use its child for its bounding box --> + <div style="visibility:hidden" aria-hidden=false> + <div style="visibility:visible"> + Visible text + </div> + </div> +``` + +* If a node still has no size after that union, its bounds will be set to the +size of the nearest ancestor which has size. However, this node will be marked +`offscreen`, because it isn't visible to the user. + + * This is useful for exposing nodes to screen reader users. + +In addition, [AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc) +is used to determine how location and size may be clipped by ancestors, +allowing bounding boxes to reflect the location of a node clipped to its +ancestors. + +* If a node is fully clipped by its ancestors such that the intersection of its +bounds and an ancestor's bounds are size 0, it will be pushed to the nearest +edge of the ancestor with width 1 or height 1. + + * We use width and height 1 instead of 0 to distinguish between empty or + unknown sized nodes vs known small or clipped sized nodes. + +Both clipped and unclipped location and size are exposed through the +[Chrome automation API](https://developer.chrome.com/extensions/automation). + +* `location` is the global location of a node as clipped by its ancestors. If +a node is fully scrolled off a rootWebArea in X, for example, its location will +be the height of the rootWebArea, and its height will be 1. The Y position and width will be unchanged. + +* `unclippedLocation` is the global location of a node ignoring any clipping +by ancestors. If a node is fully scrolled off a rootWebArea in X, for example, +its location will simply be larger than the height of the rootWebArea, and its +size will also be unchanged.
diff --git a/ios/web/navigation/navigation_manager_delegate.h b/ios/web/navigation/navigation_manager_delegate.h index 3266aa34..2d7698bc 100644 --- a/ios/web/navigation/navigation_manager_delegate.h +++ b/ios/web/navigation/navigation_manager_delegate.h
@@ -68,6 +68,11 @@ // Returns a CRWWebViewNavigationProxy protocol that can be used to access // navigation related functions on the main WKWebView. virtual id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const = 0; + + // Instructs the delegate to remove the underlying web view. The only use case + // currently is to clear back-forward history in web view before restoring + // session history. + virtual void RemoveWebView() = 0; }; } // namespace web
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index 9f8b94f3..a642c9c5 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -81,6 +81,7 @@ MOCK_METHOD1(OnNavigationItemsPruned, void(size_t)); MOCK_METHOD0(OnNavigationItemChanged, void()); MOCK_METHOD1(OnNavigationItemCommitted, void(const LoadCommittedDetails&)); + MOCK_METHOD0(RemoveWebView, void()); private: WebState* GetWebState() override { return nullptr; }
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm index d21ed98..f582e51 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -361,12 +361,20 @@ void WKBasedNavigationManagerImpl::Restore( int last_committed_item_index, std::vector<std::unique_ptr<NavigationItem>> items) { - DCHECK(GetItemCount() == 0 && !GetPendingItem()); DCHECK_LT(last_committed_item_index, static_cast<int>(items.size())); DCHECK(items.empty() || last_committed_item_index >= 0); if (items.empty()) return; + DiscardNonCommittedItems(); + if (GetItemCount() > 0) { + delegate_->RemoveWebView(); + } + DCHECK_EQ(0, GetItemCount()); + pending_item_index_ = -1; + previous_item_index_ = -1; + last_committed_item_index_ = -1; + // This function restores session history by loading a magic local file // (restore_session.html) into the web view. The session history is encoded // in the query parameter. When loaded, restore_session.html parses the
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm index 9f36b622..1a29a13 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
@@ -61,6 +61,10 @@ class MockNavigationManagerDelegate : public NavigationManagerDelegate { public: void SetWebViewNavigationProxy(id web_view) { mock_web_view_ = web_view; } + void RemoveWebView() override { + // Simulate removing the web view. + mock_web_view_ = nil; + } MOCK_METHOD0(ClearTransientContent, void()); MOCK_METHOD0(RecordPageStateInNavigationItem, void()); @@ -590,6 +594,66 @@ session_json); } +// Tests that restoring session replaces existing history in navigation manager. +TEST_F(WKBasedNavigationManagerTest, RestoreSessionResetsHistory) { + EXPECT_EQ(-1, manager_->GetPendingItemIndex()); + EXPECT_EQ(-1, manager_->GetPreviousItemIndex()); + EXPECT_EQ(-1, manager_->GetLastCommittedItemIndex()); + + // Sets up the navigation history with 2 entries, and a pending back-forward + // navigation so that last_committed_item_index is 1, pending_item_index is 0, + // and previous_item_index is 0. Basically, none of them is -1. + manager_->AddPendingItem( + GURL("http://www.url.com/0"), Referrer(), ui::PAGE_TRANSITION_TYPED, + web::NavigationInitiationType::USER_INITIATED, + web::NavigationManager::UserAgentOverrideOption::INHERIT); + [mock_wk_list_ setCurrentURL:@"http://www.url.com/0"]; + manager_->CommitPendingItem(); + + manager_->AddPendingItem( + GURL("http://www.url.com/1"), Referrer(), ui::PAGE_TRANSITION_TYPED, + web::NavigationInitiationType::USER_INITIATED, + web::NavigationManager::UserAgentOverrideOption::INHERIT); + [mock_wk_list_ setCurrentURL:@"http://www.url.com/1" + backListURLs:@[ @"http://www.url.com/0" ] + forwardListURLs:nil]; + manager_->CommitPendingItem(); + + [mock_wk_list_ moveCurrentToIndex:0]; + OCMStub([mock_web_view_ URL]) + .andReturn([NSURL URLWithString:@"http://www.url.com/0"]); + manager_->AddPendingItem( + GURL("http://www.url.com/0"), Referrer(), ui::PAGE_TRANSITION_TYPED, + web::NavigationInitiationType::USER_INITIATED, + web::NavigationManager::UserAgentOverrideOption::INHERIT); + + EXPECT_EQ(1, manager_->GetLastCommittedItemIndex()); + EXPECT_EQ(0, manager_->GetPreviousItemIndex()); + EXPECT_EQ(0, manager_->GetPendingItemIndex()); + EXPECT_TRUE(manager_->GetPendingItem() != nullptr); + + // Restores a fake session. + std::vector<std::unique_ptr<NavigationItem>> items; + items.push_back(base::MakeUnique<NavigationItemImpl>()); + manager_->Restore(0 /* last_committed_item_index */, std::move(items)); + + // Check that last_committed_index, previous_item_index and pending_item_index + // are all reset to -1. Note that last_committed_item_index will change to the + // value in the restored session (i.e. 0) once restore_session.html finishes + // loading in the web view. This is not tested here because this test doesn't + // use real WKWebView. + EXPECT_EQ(-1, manager_->GetLastCommittedItemIndex()); + EXPECT_EQ(-1, manager_->GetPreviousItemIndex()); + EXPECT_EQ(-1, manager_->GetPendingItemIndex()); + + // Check that the only pending item is restore_session.html. + NavigationItem* pending_item = manager_->GetPendingItem(); + ASSERT_TRUE(pending_item != nullptr); + GURL pending_url = pending_item->GetURL(); + EXPECT_TRUE(pending_url.SchemeIsFile()); + EXPECT_EQ("restore_session.html", pending_url.ExtractFileName()); +} + // Tests that Restore() accepts empty session history and performs no-op. TEST_F(WKBasedNavigationManagerTest, RestoreSessionWithEmptyHistory) { EXPECT_CALL(delegate_, WillLoadCurrentItemWithUrl(testing::_)).Times(0);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.h b/ios/web/test/fakes/fake_navigation_manager_delegate.h index d4745b9..5716aac 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.h +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.h
@@ -28,6 +28,7 @@ const LoadCommittedDetails& load_details) override; WebState* GetWebState() override; id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const override; + void RemoveWebView() override; // Setters for tests to inject dependencies. void SetWebViewNavigationProxy(id test_web_view);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.mm b/ios/web/test/fakes/fake_navigation_manager_delegate.mm index 1c80701d..0932b3dd 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.mm +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.mm
@@ -32,6 +32,7 @@ FakeNavigationManagerDelegate::GetWebViewNavigationProxy() const { return test_web_view_; } +void FakeNavigationManagerDelegate::RemoveWebView() {} void FakeNavigationManagerDelegate::SetWebViewNavigationProxy(id web_view) { test_web_view_ = web_view;
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index 149506c..1fc59f6 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -118,6 +118,11 @@ // WebStateImpl API instead of calling this method directly. - (void)clearTransientContentView; +// Removes the back WebView. DANGER: this method is exposed for the sole purpose +// of allowing WKBasedNavigationManagerImpl to reset the back-forward history. +// Please reconsider before using this method. +- (void)removeWebView; + // Call to stop the CRWWebController from doing stuff, in particular to // stop all network requests. Called as part of the close sequence if it hasn't // already been halted; also called from [Tab halt] as part of the shutdown
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 0d8ff80..4898a23 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -509,8 +509,6 @@ // Wraps the web view in a CRWWebViewContentView and adds it to the container // view. - (void)displayWebView; -// Removes webView. -- (void)removeWebView; // Called when web view process has been terminated. - (void)webViewWebProcessDidCrash; // Returns the WKWebViewConfigurationProvider associated with the web
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index 3661919e..da10e00a 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -291,6 +291,7 @@ WebState* GetWebState() override; id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const override; + void RemoveWebView() override; protected: void AddPolicyDecider(WebStatePolicyDecider* decider) override;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index b5a4ede..178893d 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -809,6 +809,10 @@ return [web_controller_ webViewNavigationProxy]; } +void WebStateImpl::RemoveWebView() { + return [web_controller_ removeWebView]; +} + void WebStateImpl::RestoreSessionStorage(CRWSessionStorage* session_storage) { SessionStorageBuilder session_storage_builder; session_storage_builder.ExtractSessionState(this, session_storage);
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 246da295..8de633a 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -17,11 +17,11 @@ crbug.com/707656 editing/undo/undo-indent.html [ Crash Pass ] crbug.com/707656 external/wpt/html/editing/editing-0/spelling-and-grammar-checking/spelling-markers-001.html [ Crash Pass ] crbug.com/707656 external/wpt/html/editing/focus/processing-model/focus-fixup-rule-one-no-dialogs.html [ Crash Pass ] -crbug.com/789878 fast/css/first-letter-capitalized-edit-select-crash.html [ Failure ] +crbug.com/789878 fast/css/first-letter-capitalized-edit-select-crash.html [ Failure Pass ] crbug.com/707656 fast/css/readwrite-contenteditable-recalc.html [ Crash Pass ] -crbug.com/789878 fast/css/readwrite-contenteditable.html [ Failure ] +crbug.com/789878 fast/css/readwrite-contenteditable.html [ Failure Pass ] crbug.com/707656 fast/inline-block/14498-positionForCoordinates.html [ Failure Pass ] -crbug.com/789878 fast/inline/inline-focus-ring.html [ Failure ] +crbug.com/789878 fast/inline/inline-focus-ring.html [ Failure Pass ] crbug.com/707656 paint/invalidation/remove-anonymous-block-crash.html [ Crash Pass ] # TextIterator differ in trailing spaces. @@ -50,7 +50,7 @@ # Non-interoperable behavior not worth to fix. crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Skip ] -crbug.com/714962 intersection-observer/text-target.html [ Failure ] +crbug.com/714962 intersection-observer/text-target.html [ Failure Pass ] # New passes crbug.com/626703 external/wpt/css/css-ui/text-overflow-021.html [ Failure ] @@ -126,7 +126,7 @@ crbug.com/591099 accessibility/textarea-caret-position.html [ Failure Timeout ] crbug.com/591099 accessibility/textarea-selection.html [ Failure ] crbug.com/591099 accessibility/whitespace-in-name-calc.html [ Failure ] -crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Pass ] +crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Pass Timeout ] crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ] crbug.com/591099 animations/interpolation/backdrop-filter-interpolation.html [ Timeout ] crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Pass Timeout ] @@ -1196,7 +1196,7 @@ crbug.com/591099 css3/masking/clip-path-circle-overflow-hidden.html [ Failure ] crbug.com/591099 css3/masking/clip-path-circle-overflow.html [ Failure ] crbug.com/591099 css3/masking/clip-path-circle-relative-overflow.html [ Failure ] -crbug.com/591099 css3/masking/clip-path-circle.html [ Failure ] +crbug.com/591099 css3/masking/clip-path-circle.html [ Crash Failure ] crbug.com/591099 css3/masking/clip-path-ellipse.html [ Failure ] crbug.com/591099 css3/masking/clip-path-inset-corners.html [ Failure ] crbug.com/591099 css3/masking/clip-path-polygon-evenodd.html [ Failure ] @@ -1974,16 +1974,16 @@ crbug.com/591099 editing/assert_selection.html [ Failure ] crbug.com/591099 editing/caret/caret-color-001.html [ Failure ] crbug.com/591099 editing/caret/caret-color-002.html [ Crash Failure ] -crbug.com/591099 editing/caret/caret-color-003.html [ Failure ] +crbug.com/591099 editing/caret/caret-color-003.html [ Crash Failure Timeout ] crbug.com/591099 editing/caret/caret-color-004.html [ Crash Failure ] -crbug.com/591099 editing/caret/caret-color-005.html [ Failure ] +crbug.com/591099 editing/caret/caret-color-005.html [ Failure Timeout ] crbug.com/591099 editing/caret/caret-color-007.html [ Crash Failure ] crbug.com/591099 editing/caret/caret-color-010.html [ Crash Failure Timeout ] crbug.com/591099 editing/caret/caret-color-011.html [ Failure ] crbug.com/591099 editing/caret/caret-color-012.html [ Crash Failure ] crbug.com/591099 editing/caret/caret-color-014.html [ Crash Failure ] crbug.com/591099 editing/caret/caret-color-015.html [ Crash Failure Timeout ] -crbug.com/591099 editing/caret/caret-color.html [ Failure ] +crbug.com/591099 editing/caret/caret-color.html [ Crash Failure ] crbug.com/591099 editing/caret/caret-in-empty-cell.html [ Crash Failure Pass Timeout ] crbug.com/591099 editing/caret/caret-position.html [ Crash Failure Timeout ] crbug.com/591099 editing/deleting/4922367.html [ Failure ] @@ -2106,7 +2106,7 @@ crbug.com/591099 editing/pasteboard/5761530-1.html [ Failure ] crbug.com/591099 editing/pasteboard/7955.html [ Failure ] crbug.com/591099 editing/pasteboard/bad-placeholder.html [ Failure ] -crbug.com/591099 editing/pasteboard/copy-backslash-with-euc.html [ Crash ] +crbug.com/591099 editing/pasteboard/copy-backslash-with-euc.html [ Crash Pass ] crbug.com/591099 editing/pasteboard/copy-in-password-field.html [ Failure ] crbug.com/591099 editing/pasteboard/copy-paste-white-space.html [ Crash ] crbug.com/591099 editing/pasteboard/copy-standalone-image.html [ Failure ] @@ -2164,7 +2164,7 @@ crbug.com/591099 editing/selection/6476.html [ Failure ] crbug.com/591099 editing/selection/caret-and-focus-ring.html [ Failure ] crbug.com/591099 editing/selection/caret-at-bidi-boundary.html [ Failure ] -crbug.com/591099 editing/selection/caret-in-empty-inline-2.html [ Failure ] +crbug.com/591099 editing/selection/caret-in-empty-inline-2.html [ Failure Pass ] crbug.com/591099 editing/selection/caret-ltr-2-left.html [ Failure ] crbug.com/591099 editing/selection/caret-ltr-2.html [ Failure ] crbug.com/591099 editing/selection/caret-ltr-right.html [ Failure ] @@ -2410,7 +2410,7 @@ crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-005.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-006.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-007.html [ Failure ] -crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-008.html [ Failure ] +crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-008.html [ Crash Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-009.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-011.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-012.html [ Failure ] @@ -3811,7 +3811,7 @@ crbug.com/591099 fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ] crbug.com/591099 fast/events/autoscroll-upwards-propagation-overflow-hidden-iframe-body.html [ Failure ] crbug.com/591099 fast/events/autoscroll-with-non-scrollable-parent.html [ Failure ] -crbug.com/591099 fast/events/autoscroll.html [ Failure ] +crbug.com/591099 fast/events/autoscroll.html [ Failure Pass ] crbug.com/591099 fast/events/change-frame-focus.html [ Failure ] crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ] crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ] @@ -4233,7 +4233,7 @@ crbug.com/591099 fast/forms/textarea/textarea-no-scroll-on-blur.html [ Failure ] crbug.com/591099 fast/forms/textarea/textarea-placeholder-visibility-1.html [ Failure ] crbug.com/591099 fast/forms/textarea/textarea-placeholder-visibility-2.html [ Failure ] -crbug.com/591099 fast/forms/textarea/textarea-resize-orthogonal-containing-block.html [ Failure ] +crbug.com/591099 fast/forms/textarea/textarea-resize-orthogonal-containing-block.html [ Failure Timeout ] crbug.com/591099 fast/forms/textarea/textarea-scroll-height.html [ Failure ] crbug.com/591099 fast/forms/textarea/textarea-scrollbar.html [ Failure ] crbug.com/591099 fast/forms/textarea/textarea-scrolled-focus-ring.html [ Failure ] @@ -4407,7 +4407,7 @@ crbug.com/591099 fast/js/same-origin-subframe-about-blank.html [ Failure ] crbug.com/591099 fast/js/toString-and-valueOf-override.html [ Failure ] crbug.com/591099 fast/js/webidl-type-mapping.html [ Timeout ] -crbug.com/591099 fast/layers/add-layer-with-nested-stacking.html [ Failure ] +crbug.com/591099 fast/layers/add-layer-with-nested-stacking.html [ Crash Failure ] crbug.com/591099 fast/layers/inline-dirty-z-order-lists.html [ Crash ] crbug.com/591099 fast/layers/layer-content-visibility-change.html [ Failure ] crbug.com/591099 fast/layers/layer-visibility-sublayer.html [ Failure ] @@ -4903,6 +4903,7 @@ crbug.com/591099 fast/overflow/infiniteRecursionGuard.html [ Failure ] crbug.com/591099 fast/overflow/line-clamp.html [ Failure ] crbug.com/591099 fast/overflow/onscroll-layer-self-destruct.html [ Timeout ] +crbug.com/591099 fast/overflow/overflow-of-video-outline.html [ Failure ] crbug.com/591099 fast/overflow/overflow-rtl-vertical.html [ Failure ] crbug.com/591099 fast/overflow/overflow-rtl.html [ Failure ] crbug.com/591099 fast/overflow/overflow-update-transform.html [ Failure ] @@ -4910,7 +4911,6 @@ crbug.com/591099 fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto.html [ Failure ] crbug.com/591099 fast/overflow/scrollbar-restored-and-then-locked.html [ Failure ] crbug.com/591099 fast/overflow/scrollbar-restored.html [ Failure ] -crbug.com/591099 fast/overflow/overflow-of-video-outline.html [ Failure ] crbug.com/591099 fast/pagination/auto-height-with-break.html [ Failure ] crbug.com/591099 fast/pagination/break-in-paged-overflow.html [ Failure ] crbug.com/591099 fast/pagination/caret-range-outside-paged-x-rtl.html [ Failure ] @@ -4976,9 +4976,15 @@ crbug.com/591099 external/wpt/css/CSS2/positioning/absolute-replaced-height-001.xht [ Failure ] crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-table-002-none.html [ Crash ] crbug.com/591099 external/wpt/css/css-display/display-contents-replaced-001.html [ Crash ] +crbug.com/591099 external/wpt/css/css-display/display-contents-text-inherit.html [ Pass ] crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems-2.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-003.html [ Pass ] +crbug.com/591099 external/wpt/css/css-fonts/font-variant-01.html [ Pass ] +crbug.com/591099 external/wpt/css/css-fonts/font-variant-02.html [ Pass ] +crbug.com/591099 external/wpt/css/css-fonts/font-variant-03.html [ Pass ] +crbug.com/591099 external/wpt/css/css-fonts/font-variant-04.html [ Pass ] +crbug.com/591099 external/wpt/css/css-fonts/matching/fixed-stretch-style-over-weight.html [ Pass ] crbug.com/591099 external/wpt/css/css-fonts/test_font_family_parsing.html [ Timeout ] crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-002.html [ Failure ] crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-005.html [ Failure ] @@ -4997,6 +5003,116 @@ crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-012.html [ Failure ] crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-015.html [ Failure ] crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-016.html [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-001.html [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-002.html [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-003.html [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-004.html [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-007.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-008.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-br-inside-avoidcolumn-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-break-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-break-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-004.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-005.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-006.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-007.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-toolong-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-block-children-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-balance-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-fraction-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-negative-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-height-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-list-item-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-margin-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-005.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-004.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-005.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-overflow-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-reduce-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dashed-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dotted-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-double-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-groove-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-ridge-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-solid-000.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-groove-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-ridge-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-000.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-block-sibling-003.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-child-001.xht [ Crash Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-002.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-003.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-span-none-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ] crbug.com/591099 external/wpt/css/css-position/position-sticky-nested-inline.html [ Crash ] crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Crash ] crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Crash ] @@ -5160,6 +5276,7 @@ crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Pass Timeout ] crbug.com/591099 external/wpt/websockets/cookies/005.html [ Pass ] crbug.com/591099 external/wpt/websockets/cookies/007.html [ Failure Pass ] +crbug.com/591099 external/wpt/websockets/opening-handshake/005.html [ Failure Pass ] crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html [ Crash ] crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html [ Crash ] crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html [ Crash ] @@ -5270,120 +5387,11 @@ crbug.com/591099 fast/inline/inline-width-containing-collapsed-whitespace-and-image-in-float.html [ Failure ] crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ] crbug.com/591099 fast/lists/list-and-grid.html [ Failure ] +crbug.com/591099 fast/lists/list-and-margin-collapse.html [ Failure ] crbug.com/591099 fast/lists/list-marker-inside-overflow-hidden.html [ Failure ] crbug.com/591099 fast/lists/remove-listmarker-from-anonblock-with-continuation-crash.html [ Crash ] crbug.com/591099 fast/loader/javascript-url-iframe-crash.html [ Crash ] crbug.com/591099 fast/media/mq-display-mode-fullscreen.html [ Crash ] -crbug.com/591099 external/wpt/css/css-fonts/matching/fixed-stretch-style-over-weight.html [ Pass ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-001.html [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-002.html [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-003.html [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-004.html [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-007.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-008.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-break-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-004.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-005.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-006.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-007.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-toolong-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-block-children-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-balance-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-fraction-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-negative-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-height-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-list-item-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-margin-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-005.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-004.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-005.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-overflow-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-reduce-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dashed-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dotted-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-double-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-groove-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-ridge-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-solid-000.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-groove-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-ridge-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-000.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-block-sibling-003.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-child-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-002.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-003.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-span-none-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ] -crbug.com/591099 external/wpt/websockets/opening-handshake/005.html [ Pass ] crbug.com/591099 fast/overflow/overflow-visible-should-ignore-scroll.html [ Failure ] crbug.com/591099 fast/pagination/div-x-vertical-lr-ltr.html [ Failure ] crbug.com/591099 fast/pagination/div-x-vertical-lr-rtl.html [ Failure ] @@ -5615,12 +5623,12 @@ crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-dynamic-shape.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-edge-case.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon.html [ Failure ] -crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-border-box.html [ Failure ] +crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-border-box.html [ Crash Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-content-box.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-padding-box.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-border-box.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-content-box.html [ Failure ] -crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-padding-box.html [ Failure ] +crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-padding-box.html [ Crash Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html [ Failure ] @@ -5670,7 +5678,7 @@ crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-relative-size-svg.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-001.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-002.html [ Failure ] -crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-inset.html [ Failure ] +crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-inset.html [ Crash Failure ] crbug.com/591099 fast/spatial-navigation/snav-clipped-overflowed-content.html [ Failure ] crbug.com/591099 fast/spatial-navigation/snav-container-white-space.html [ Failure ] crbug.com/591099 fast/spatial-navigation/snav-fully-aligned-vertically.html [ Failure ] @@ -6233,7 +6241,7 @@ crbug.com/591099 http/tests/devtools/console/shadow-element.js [ Crash Timeout ] crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Crash Timeout ] crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ] -crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash Timeout ] +crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash Pass Timeout ] crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-4.html [ Timeout ] crbug.com/591099 http/tests/devtools/elements/elements-panel-restore-selection-when-node-comes-later.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery1.js [ Failure ] @@ -6245,7 +6253,6 @@ crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scroll.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node.js [ Failure ] -crbug.com/591099 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-2/add-import-rule.html [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet.html [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Failure Pass ] @@ -6258,10 +6265,9 @@ crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.html [ Failure ] crbug.com/591099 http/tests/devtools/extensions/extensions-timeline-api.html [ Failure ] crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure Timeout ] -crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure ] +crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure Timeout ] crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ] crbug.com/591099 http/tests/devtools/network/network-disable-cache-preloads.php [ Failure ] -crbug.com/591099 http/tests/devtools/network/network-memory-cached-resource.js [ Failure ] crbug.com/591099 http/tests/devtools/persistence/automapping-sourcemap-nameclash.js [ Failure ] crbug.com/591099 http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js [ Failure ] crbug.com/591099 http/tests/devtools/runtime/runtime-getProperties.js [ Failure ] @@ -6925,7 +6931,7 @@ crbug.com/591099 paint/invalidation/multicol/multicol-with-block.html [ Failure ] crbug.com/591099 paint/invalidation/multicol/multicol-with-inline.html [ Failure ] crbug.com/591099 paint/invalidation/multicol/multicol-with-overflowing-block-rl.html [ Failure ] -crbug.com/591099 paint/invalidation/multicol/multicol-with-relpos.html [ Failure ] +crbug.com/591099 paint/invalidation/multicol/multicol-with-relpos.html [ Crash Failure ] crbug.com/591099 paint/invalidation/multicol/multicol-with-text.html [ Failure ] crbug.com/591099 paint/invalidation/non-text-link-invalidation-optimization.html [ Failure ] crbug.com/591099 paint/invalidation/offset-change-wrong-invalidation-with-float.html [ Failure ] @@ -7154,7 +7160,7 @@ crbug.com/591099 paint/invalidation/svg/embedded-svg-size-changes-no-layout-triggers.html [ Failure ] crbug.com/591099 paint/invalidation/svg/foreign-object-repaint.svg [ Failure ] crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ] -crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ] +crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Crash Failure ] crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure ] crbug.com/591099 paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ] crbug.com/591099 paint/invalidation/svg/overflow-repaint.html [ Failure ] @@ -7383,7 +7389,7 @@ crbug.com/591099 printing/page-break-margin-collapsed.html [ Failure ] crbug.com/591099 printing/page-break-orphans-and-widows.html [ Failure ] crbug.com/591099 printing/page-break-orphans.html [ Failure ] -crbug.com/591099 printing/page-break-widows.html [ Failure ] +crbug.com/591099 printing/page-break-widows.html [ Crash Failure ] crbug.com/591099 printing/page-count-relayout-shrink.html [ Failure ] crbug.com/591099 printing/quirks-percentage-height-body.html [ Failure ] crbug.com/591099 printing/quirks-percentage-height.html [ Failure ] @@ -7395,7 +7401,7 @@ crbug.com/591099 printing/subframes-percentage-height.html [ Failure ] crbug.com/591099 printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables.html [ Failure ] crbug.com/591099 printing/tfoot-repeats-at-bottom-of-each-page.html [ Failure ] -crbug.com/591099 printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Failure ] +crbug.com/591099 printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Crash Failure ] crbug.com/591099 printing/thead-repeats-at-top-of-each-page.html [ Failure ] crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ] crbug.com/591099 scrollbars/custom-scrollbar-enable-changes-thickness-with-iframe.html [ Failure ] @@ -7602,7 +7608,7 @@ crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ] crbug.com/591099 svg/custom/invisible-text-after-scrolling.xhtml [ Failure ] crbug.com/591099 svg/custom/junk-data.svg [ Failure ] -crbug.com/591099 svg/custom/load-non-wellformed.svg [ Failure ] +crbug.com/591099 svg/custom/load-non-wellformed.svg [ Crash Failure ] crbug.com/591099 svg/custom/marker-orient-auto.html [ Failure ] crbug.com/591099 svg/custom/missing-xlink.svg [ Failure ] crbug.com/591099 svg/custom/mouse-move-on-svg-container.xhtml [ Timeout ] @@ -7654,7 +7660,7 @@ crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-target-prop.html [ Failure ] crbug.com/591099 svg/dynamic-updates/SVGClipPath-influences-hitTesting.html [ Failure ] crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-css-transform-influences-hitTesting.html [ Failure ] -crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Failure ] +crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Crash Failure ] crbug.com/591099 svg/filters/feBlend-all-modes.html [ Failure ] crbug.com/591099 svg/filters/feTurbulence-bad-seeds.html [ Crash Failure ] crbug.com/591099 svg/foreign-object-under-shadow-root-under-hidden.html [ Failure ] @@ -7668,7 +7674,7 @@ crbug.com/591099 svg/foreignObject/no-crash-with-svg-content-in-html-document.svg [ Failure ] crbug.com/591099 svg/foreignObject/svg-document-in-html-document.svg [ Failure ] crbug.com/591099 svg/hittest/clip-path-shape.html [ Failure ] -crbug.com/591099 svg/hittest/ellipse-hittest.html [ Failure ] +crbug.com/591099 svg/hittest/ellipse-hittest.html [ Crash Failure ] crbug.com/591099 svg/hittest/empty-container.html [ Failure ] crbug.com/591099 svg/hittest/pointer-events-all.html [ Failure ] crbug.com/591099 svg/hittest/pointer-events-all2.html [ Failure ] @@ -7708,7 +7714,7 @@ crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-auto.xhtml [ Failure ] crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ] crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-hidden.xhtml [ Failure ] -crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Failure ] +crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Crash Failure ] crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-visible.xhtml [ Failure ] crbug.com/591099 svg/parser/whitespace-length-invalid-1.html [ Pass Timeout ] crbug.com/591099 svg/parser/whitespace-length-invalid-2.html [ Pass Timeout ] @@ -7830,7 +7836,7 @@ crbug.com/591099 tables/mozilla/bugs/bug88524.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug98196.html [ Failure ] crbug.com/591099 tables/mozilla/collapsing_borders/bug41262-3.html [ Failure ] -crbug.com/591099 tables/mozilla/core/bloomberg.html [ Failure ] +crbug.com/591099 tables/mozilla/core/bloomberg.html [ Crash Failure ] crbug.com/591099 tables/mozilla/core/captions.html [ Failure ] crbug.com/591099 tables/mozilla/core/cell_heights.html [ Failure ] crbug.com/591099 tables/mozilla/core/table_heights.html [ Failure ] @@ -7948,7 +7954,7 @@ crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-image-source.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-radius.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-drag-image.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/color-profile-filter.html [ Failure ] +crbug.com/591099 virtual/gpu-rasterization/images/color-profile-filter.html [ Failure Timeout ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-group.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-iframe.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ] @@ -8025,7 +8031,7 @@ crbug.com/591099 virtual/gpu-rasterization/images/webp-flip.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/width-on-broken-data-src.html [ Failure ] crbug.com/591099 virtual/gpu-rasterization/images/zoomed-img-size.html [ Crash ] -crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass ] +crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass Timeout ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-drawImage.html [ Timeout ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-animated-images.html [ Failure ] @@ -8034,19 +8040,38 @@ crbug.com/591099 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-measure-bidi-text.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-render-layer.html [ Failure ] -crbug.com/591099 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Failure ] +crbug.com/591099 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Crash Failure Timeout ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-transforms-during-path.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/fill-stroke-clip-reset-path.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/patternfill-repeat.html [ Failure Timeout ] crbug.com/591099 virtual/high-contrast-mode/paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ] +crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/MouseEvent-prototype-offsetX-offsetY.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/shadow-root-002.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html [ Pass ] crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/focus-navigation-with-distributed-nodes.html [ Crash ] crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/form-in-shadow.html [ Crash ] crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selection-in-nested-shadow.html [ Failure ] crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selections-in-shadow.html [ Timeout ] crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/shadow-dom-event-dispatching-svg-in-shadow-subtree.html [ Failure ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/active-element.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-outer-scope2.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-slot-distributed.html [ Pass ] crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/event-composed-ua.html [ Timeout ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-nested-delegatesFocus.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-nested.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-with-tabindex.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slots.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/host-pseudo-elements.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/layout.html [ Pass ] crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/range-caret-range-from-point-left-of-shadow.html [ Crash ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-1.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-2.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-dynamic.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slotted-pseudo-element-shared-style.html [ Pass ] +crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slotted-pseudo-element.html [ Pass ] crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-replaced-width-002.xht [ Pass ] crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-static-001.xht [ Pass ] @@ -8061,8 +8086,8 @@ crbug.com/591099 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Pass ] crbug.com/591099 virtual/layout_ng/overflow/overflow-basic-003.html [ Pass ] crbug.com/591099 virtual/layout_ng/overflow/overflow-bug-chrome-ng-001.html [ Pass ] +crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure Pass ] crbug.com/591099 virtual/layout_ng_paint/fast/inline/inline-box-adjust-position-crash.html [ Pass ] -crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ] crbug.com/591099 virtual/mojo-blobs/ [ Skip ] crbug.com/591099 virtual/mojo-localstorage/ [ Skip ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/anchor-empty-focus.html [ Failure ] @@ -8072,7 +8097,7 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-upwards-propagation-overflow-hidden-iframe-body.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-with-non-scrollable-parent.html [ Failure ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll.html [ Failure ] +crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll.html [ Failure Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/change-frame-focus.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ] @@ -8124,7 +8149,7 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseover-mouseout.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/no-blur-on-enter-button.html [ Failure ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure ] +crbug.com/591099 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onblur-remove.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onchange-range-slider.html [ Crash ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ] @@ -8357,8 +8382,14 @@ crbug.com/591099 virtual/spv175/compositing/layers-inside-overflow-scroll.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/lots-of-img-layers-with-opacity.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/lots-of-img-layers.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/direct-image-mask.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/masks/mask-layer-size.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/masks/mask-of-clipped-layer.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/mask-with-added-filters.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/mask-with-removed-filters.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/masked-ancestor.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/multiple-masks.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/masks/simple-composited-mask.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/nested-border-radius-composited-child.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/ancestor-overflow.html [ Failure ] @@ -8375,6 +8406,7 @@ crbug.com/591099 virtual/spv175/compositing/overflow/fractional-sized-scrolling-layer.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/get-transform-from-non-box-container.html [ Crash ] crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-filter.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-small-content-rect.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/nested-border-radius-clipping.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ] @@ -8786,7 +8818,7 @@ crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-abspos.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-block.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-inline.html [ Failure ] -crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-relpos.html [ Failure ] +crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-relpos.html [ Crash Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-text.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/non-text-link-invalidation-optimization.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/outline/border-outline-0.html [ Failure ] @@ -8826,6 +8858,7 @@ crbug.com/591099 virtual/spv175/paint/invalidation/overflow/clipped-overflow-visible-subtree.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-borderbox-background.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-local-background.html [ Failure ] +crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-negative-offset-outline.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-vertical-rl-overflow.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/overflow/content-into-overflow.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/overflow/erase-overflow.html [ Failure ] @@ -9013,7 +9046,7 @@ crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-content.xhtml [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-deep-shadow-tree-content.xhtml [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-image.xhtml [ Failure ] -crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Failure ] +crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Crash Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol.xhtml [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-shadow-tree-content.xhtml [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-use-on-symbol.xhtml [ Crash Failure ] @@ -9024,7 +9057,7 @@ crbug.com/591099 virtual/spv175/paint/invalidation/svg/repaint-svg-after-style-change.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/resize-svg-invalidate-children-2.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/resize-svg-invalidate-children.html [ Failure ] -crbug.com/591099 virtual/spv175/paint/invalidation/svg/scroll-hit-test.xhtml [ Failure ] +crbug.com/591099 virtual/spv175/paint/invalidation/svg/scroll-hit-test.xhtml [ Crash Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ] crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-image-change-content-size.xhtml [ Failure ] @@ -9151,6 +9184,7 @@ crbug.com/591099 virtual/spv175/paint/markers/marker-early-break-bug.html [ Failure ] crbug.com/591099 virtual/spv175/paint/markers/suggestion-marker-basic.html [ Failure ] crbug.com/591099 virtual/spv175/paint/markers/suggestion-marker-split.html [ Failure ] +crbug.com/591099 virtual/spv175/paint/masks/fieldset-mask.html [ Failure ] crbug.com/591099 virtual/spv175/paint/overflow/composited-rounded-clip-floating-element.html [ Failure ] crbug.com/591099 virtual/spv175/paint/overflow/fixed-background-scroll-window.html [ Failure ] crbug.com/591099 virtual/spv175/paint/overflow/non-composited-fixed-position-descendant.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 02fd350..62a7271 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3052,15 +3052,7 @@ # crbug.com/736177: Failures likely related to different results on Mac with different GPUs crbug.com/736177 [ Mac10.12 ] fast/forms/form-element-geometry.html [ Failure Pass ] -# These tests are failing on both Mac-10.12 when using an Intel GPU and Mac-10.11.6 when using no GPU -crbug.com/736177 [ Mac ] fast/forms/control-restrict-line-height.html [ Failure Pass ] crbug.com/736177 [ Mac ] fast/forms/input-appearance-height.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/placeholder-position.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/search/search-appearance-basic.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/search/search-cancel-button-style-sharing.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/search/search-display-none-cancel-button.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/search/search-rtl.html [ Failure Pass ] -crbug.com/736177 [ Mac ] fast/forms/search/searchfield-heights.html [ Failure Pass ] # These tests are failing on Mac-10.12 when using an Intel GPU and Mac Retina crbug.com/736177 [ Mac10.12 Retina ] compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] css1/box_properties/acid_test.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js b/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js index 5ee1e8a0..6f05b42 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js +++ b/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js
@@ -1,13 +1,3 @@ -function gc() -{ - if (window.GCController) - return GCController.collectAll(); - - for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect) - var s = new String(""); - } -} - function removeScriptElement() { var s = document.getElementById('theScript'); s.parentNode.removeChild(s);
diff --git a/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled b/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled index 5ed0f0ea..e012d99 100644 --- a/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled +++ b/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled
@@ -1,18 +1,8 @@ <body> <p>Test that adding an event listener for an event with a unique name works correctly (this used to corrupt event listener map after GC).</p> <pre id=log></pre> - +<script src="../../resources/gc.js"></script> <script> -function gc() -{ - if (window.GCController) - return GCController.collect(); - - for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect) - var s = new String("abc"); - } -} - function log(message) { document.getElementById("log").innerHTML += message + "<br>";
diff --git a/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html b/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html index b1b8a06..3c1e2c2 100644 --- a/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html +++ b/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html
@@ -1,5 +1,6 @@ <html> <head> +<script src="../../resources/gc.js"></script> <script> function sendXHR() { @@ -43,18 +44,6 @@ } } -function GC() -{ - // Force GC. - if (window.GCController) - GCController.collect(); - else { - for (var i = 0; i < 10000; ++i) { - ({ }); - } - } -} - /* GLOBALS */ var XHR = new Array(); var numXHRs = 0; @@ -67,7 +56,7 @@ <div id="replaceMe"> <div> -<select id="theSelect" onblur="sendXHR();GC();"> +<select id="theSelect" onblur="sendXHR();gc();"> </select> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js b/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js index dbfd9f16..d1b4844 100644 --- a/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js +++ b/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js
@@ -2,15 +2,6 @@ "Tests that an event handler registered on two nodes still fires after one of the nodes has been GC'd." ); -function gc() { - if (window.GCController) - GCController.collect(); - else { - for (var i = 0; i < 10000; ++i) - new Object; - } -} - var clickCount = 0; function clickHandler() { ++clickCount;
diff --git a/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js b/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js index 8564dec..10fa556 100644 --- a/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js +++ b/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js
@@ -281,22 +281,6 @@ testFailed(_a + " should throw an instance of " + _e.name); } -function gc() { - if (typeof GCController !== "undefined") - GCController.collect(); - else { - function gcRec(n) { - if (n < 1) - return {}; - var temp = {i: "ab" + i + (i / 100000)}; - temp += "foo"; - gcRec(n-1); - } - for (var i = 0; i < 1000; i++) - gcRec(10) - } -} - // It's possible for an async test to call finishJSTest() before moz-test-post.js // has been parsed. function finishJSTest() @@ -324,4 +308,4 @@ testFailed(message); else testFailed("assertEq failed: " + left + "(of type " + (typeof left) + ") !== " + right + "(of type " + (typeof right) + ")"); -} \ No newline at end of file +}
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js index 0a8d555..806a8d90 100644 --- a/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js +++ b/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js
@@ -2,15 +2,6 @@ 'Tests to make sure we do not gc the constants contained by functions defined inside eval code. To pass we need to not crash.' ); -function gc() -{ - if (this.GCController) - GCController.collect(); - else - for (var i = 0; i < 10000; ++i) // Allocate a sufficient number of objects to force a GC. - ({}); -} - evalStringTest = "'test'"; evalString = "function f() { shouldBe(\"'test'\", evalStringTest) }; f()"; function doTest() {
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js index a661de8e..6f87d138 100644 --- a/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js +++ b/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js
@@ -2,15 +2,6 @@ 'Tests to make sure that dynamic scope objects are correctly protected from GC. To pass we need to not crash.' ); -function gc() -{ - if (this.GCController) - GCController.collectAll(); - else - for (var i = 0; i < 10000; ++i) // Allocate a sufficient number of objects to force a GC. - ({}); -} - (function() { try { // Immediate value for scope
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html b/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html index 09d236d2..28543199 100644 --- a/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html +++ b/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html
@@ -3,6 +3,7 @@ <html> <title>Worklet: Worklet should report context destroyed</title> <body> +<script src="../../../resources/gc.js"></script> <script> // This test was added for confirming a crash bug fix (see // https://crbug.com/657450). This should not be upstreamed to WPT because of @@ -12,16 +13,6 @@ testRunner.dumpAsText(); } -function gc() -{ - if (window.GCController) { - GCController.collect(); - } else { - for (var i = 0; i < 10000; ++i) - new Object; - } -} - function tryCrash() { document.frame.CSS.paintWorklet;
diff --git a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt deleted file mode 100644 index d25ac94..0000000 --- a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -Verify that TextTrackCue exceptions are properly messaged to developers. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS cue.startTime = Number.NaN; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS cue.startTime = Number.POSITIVE_INFINITY; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS cue.startTime = Number.NEGATIVE_INFINITY; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS cue.endTime = Number.NaN; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS cue.endTime = Number.POSITIVE_INFINITY; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS cue.endTime = Number.NEGATIVE_INFINITY; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite.. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html index 9f687da..621b8fb 100644 --- a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html +++ b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html
@@ -1,17 +1,28 @@ <!DOCTYPE html> -<script src="../../resources/js-test.js"></script> -<body> +<title>TextTrackCue exceptions are properly messaged to developers</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script> -description("Verify that TextTrackCue exceptions are properly messaged to developers."); - -var cue = new VTTCue(0, 0, "Test."); - -function testInfinityAndNaN(property) { - shouldThrow("cue." + property + " = Number.NaN;"); - shouldThrow("cue." + property + " = Number.POSITIVE_INFINITY;"); - shouldThrow("cue." + property + " = Number.NEGATIVE_INFINITY;"); +function getExceptionMsg(property) { + return "Failed to set the '" + property + + "' property on 'TextTrackCue': The provided double value is non-finite."; } - -testInfinityAndNaN("startTime"); -testInfinityAndNaN("endTime"); +var cue = new VTTCue(0, 0, "Test."); +function testProperty(property) { + var expected_exception_msg = getExceptionMsg(property); + test(function() { + var testValues = [Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]; + testValues.forEach(function(value) { + try { + cue[property] = value; + assert_unreached("should throw"); + } catch (e) { + assert_equals(e.name, "TypeError"); + assert_equals(e.message, expected_exception_msg); + } + }); + }, expected_exception_msg); +} +testProperty("startTime"); +testProperty("endTime"); </script>
diff --git a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt deleted file mode 100644 index 7f1c130..0000000 --- a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt +++ /dev/null
@@ -1,24 +0,0 @@ -Adding tracks outside the DOM tree: -PASS video.textTracks.length is 2 -PASS video.textTracks[0] is tracka.track -PASS video.textTracks[1] is trackb.track -Inserting the parent video element into the document. -PASS video.textTracks.length is 2 -PASS video.textTracks[0] is tracka.track -PASS video.textTracks[1] is trackb.track -Inserting and removing another track in the document. -PASS video.textTracks.length is 3 -PASS video.textTracks[2] is trackc.track -PASS video.textTracks.length is 2 -PASS video.textTracks[0] is tracka.track -PASS video.textTracks[1] is trackc.track -Removing the video from the document. -PASS video.textTracks.length is 2 -PASS video.textTracks[0] is tracka.track -PASS video.textTracks[1] is trackc.track -PASS video.textTracks.length is 1 -PASS video.textTracks[0] is trackc.track -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html index 78b19cf..177d083 100644 --- a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html +++ b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html
@@ -1,49 +1,36 @@ <!DOCTYPE html> -<html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<title>Adding and removing track node</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body> <script> -var video = document.createElement('video'); +test(function() { + var video = document.createElement('video'); + var tracka = document.createElement('track'); + video.appendChild(tracka); + var trackb = document.createElement('track'); + video.appendChild(trackb); -var tracka = document.createElement('track'); -video.appendChild(tracka); -var trackb = document.createElement('track'); -video.appendChild(trackb); + // Adding tracks outside the DOM tree. + assert_array_equals(video.textTracks, [tracka.track, trackb.track]); -debug("Adding tracks outside the DOM tree:"); -shouldBe("video.textTracks.length", "2"); -shouldBe("video.textTracks[0]", "tracka.track"); -shouldBe("video.textTracks[1]", "trackb.track"); + // Inserting the parent video element into the document. + document.body.appendChild(video); + assert_array_equals(video.textTracks, [tracka.track, trackb.track]); -debug("Inserting the parent video element into the document."); -document.body.appendChild(video); -shouldBe("video.textTracks.length", "2"); -shouldBe("video.textTracks[0]", "tracka.track"); -shouldBe("video.textTracks[1]", "trackb.track"); + // Inserting and removing another track in the document. + var trackc = document.createElement('track'); + video.appendChild(trackc); + assert_array_equals(video.textTracks, [tracka.track, trackb.track, trackc.track]); -debug("Inserting and removing another track in the document."); -var trackc = document.createElement('track'); -video.appendChild(trackc); -shouldBe("video.textTracks.length", "3"); -shouldBe("video.textTracks[2]", "trackc.track"); + trackb.parentNode.removeChild(trackb); + assert_array_equals(video.textTracks, [tracka.track, trackc.track]); -trackb.parentNode.removeChild(trackb); -shouldBe("video.textTracks.length", "2"); -shouldBe("video.textTracks[0]", "tracka.track"); -shouldBe("video.textTracks[1]", "trackc.track"); + // Removing the video from the document. + document.body.removeChild(video); + assert_array_equals(video.textTracks, [tracka.track, trackc.track]); -debug("Removing the video from the document."); -document.body.removeChild(video); -shouldBe("video.textTracks.length", "2"); -shouldBe("video.textTracks[0]", "tracka.track"); -shouldBe("video.textTracks[1]", "trackc.track"); - -tracka.parentNode.removeChild(tracka); -shouldBe("video.textTracks.length", "1"); -shouldBe("video.textTracks[0]", "trackc.track"); - + tracka.parentNode.removeChild(tracka); + assert_array_equals(video.textTracks, [trackc.track]); +}); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt deleted file mode 100644 index bf9f891a..0000000 --- a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -Verify that VTTCue exceptions are properly messaged to developers. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS cue.position = -1; threw exception IndexSizeError: Failed to set the 'position' property on 'VTTCue': The value provided (-1) is outside the range [0, 100].. -PASS cue.position = 101; threw exception IndexSizeError: Failed to set the 'position' property on 'VTTCue': The value provided (101) is outside the range [0, 100].. -PASS cue.size = -1; threw exception IndexSizeError: Failed to set the 'size' property on 'VTTCue': The value provided (-1) is outside the range [0, 100].. -PASS cue.size = 101; threw exception IndexSizeError: Failed to set the 'size' property on 'VTTCue': The value provided (101) is outside the range [0, 100].. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html index 250beff2..d9bcd73 100644 --- a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html +++ b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html
@@ -1,21 +1,28 @@ <!DOCTYPE html> -<html> -<head> - <script src="../../resources/js-test.js"></script> -</head> -<body> - <script> - description("Verify that VTTCue exceptions are properly messaged to developers."); - - var cue = new VTTCue(0, 0, "Test."); - - function testPercentage(property) { - shouldThrow("cue." + property + " = -1;"); - shouldThrow("cue." + property + " = 101;"); +<title>VTTCue exceptions are properly messaged to developers</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +function getExceptionMsg(property, value) { + return "Failed to set the '" + property + + "' property on 'VTTCue': The value provided (" + + value + ") is outside the range [0, 100]."; +} +var cue = new VTTCue(0, 0, "Test."); +function testProperty(property, value) { + var expected_exception_msg = getExceptionMsg(property, value); + test(function() { + try { + cue[property] = value; + assert_unreached("should throw"); + } catch (e) { + assert_equals(e.name, "IndexSizeError"); + assert_equals(e.message, expected_exception_msg); } - - testPercentage("position"); - testPercentage("size"); - </script> -</body> -</html> + }, expected_exception_msg); +} +testProperty("position", -1); +testProperty("position", 101); +testProperty("size", -1); +testProperty("size", 101); +</script>
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png index c3e43642..a02800c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png index aee0d16..5250014 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png index e27915f..9fa610af 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png index f9c63c62..9021df3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png index b0c96eda..1cc9b4c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png index 1612592..588a6d0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png index 68da93f71..4755d06 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png index acf9689..0e30d3f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png index 37620a2..db2c8ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png index 40ca375..e11f5c8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt new file mode 100644 index 0000000..16f973e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt
@@ -0,0 +1,62 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x576 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 54x18 + text run at (0,0) width 54: "Test for " + LayoutInline {I} at (0,0) size 702x18 + LayoutInline {A} at (0,0) size 304x18 [color=#0000EE] + LayoutText {#text} at (53,0) size 304x18 + text run at (53,0) width 304: "http://bugs.webkit.org/show_bug.cgi?id=11916" + LayoutText {#text} at (356,0) size 399x18 + text run at (356,0) width 5: " " + text run at (360,0) width 395: "REGRESSION (SearchField): RTL search fields are mixed up" + LayoutText {#text} at (754,0) size 5x18 + text run at (754,0) width 5: "." + LayoutBlockFlow {P} at (0,34) size 784x57 + LayoutTextControl {INPUT} at (0,0) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (4,3) size 125x13 + LayoutBlockFlow {DIV} at (12,0) size 113x13 + LayoutText {#text} at (133,0) size 4x18 + text run at (133,0) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutTextControl {INPUT} at (0,19) size 193x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (4,3) size 185x13 + LayoutBlockFlow {DIV} at (12,0) size 173x13 + LayoutText {#text} at (193,19) size 4x18 + text run at (193,19) width 4: " " + LayoutBR {BR} at (0,0) size 0x0 + LayoutTextControl {INPUT} at (0,38) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (4,3) size 125x13 + LayoutBlockFlow {DIV} at (12,0) size 113x13 + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {P} at (0,107) size 784x18 + LayoutText {#text} at (0,0) size 37x18 + text run at (0,0) width 37: "PASS" +layer at (24,45) size 113x13 scrollX 1.00 scrollWidth 115 + LayoutBlockFlow {DIV} at (0,0) size 113x13 + LayoutText {#text} at (-1,0) size 115x13 + text run at (-1,0) width 21 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" + text run at (19,0) width 9: "B" + text run at (27,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " + text run at (69,0) width 8: "A" + text run at (76,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} " +layer at (24,64) size 173x13 + LayoutBlockFlow {DIV} at (0,0) size 173x13 + LayoutText {#text} at (58,0) size 115x13 + text run at (58,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" + text run at (79,0) width 9: "B" + text run at (87,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " + text run at (129,0) width 8: "A" + text run at (136,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} " +layer at (24,83) size 113x13 + LayoutBlockFlow {DIV} at (0,0) size 113x13 +layer at (12,46) size 11x11 transparent + LayoutBlockFlow {DIV} at (0,1) size 11x11 +layer at (12,65) size 11x11 transparent + LayoutBlockFlow {DIV} at (0,1) size 11x11 +layer at (12,84) size 11x11 transparent + LayoutBlockFlow {DIV} at (0,1) size 11x11 +caret: position 0 of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 9 {INPUT} of child 3 {P} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt new file mode 100644 index 0000000..9df5ced --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt
@@ -0,0 +1,40 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutText {#text} at (0,0) size 376x18 + text run at (0,0) width 376: "This tests that aqua-style search fields do not honor height." + LayoutBR {BR} at (375,14) size 1x0 + LayoutTextControl {INPUT} at (0,23) size 110x15 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (3,2) size 104x11 + LayoutBlockFlow {DIV} at (0,0) size 94x11 + LayoutText {#text} at (110,20) size 4x18 + text run at (110,20) width 4: " " + LayoutTextControl {INPUT} at (114,20) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (4,3) size 125x13 + LayoutBlockFlow {DIV} at (0,0) size 113x13 + LayoutText {#text} at (247,20) size 4x18 + text run at (247,20) width 4: " " + LayoutTextControl {INPUT} at (251,18) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutFlexibleBox {DIV} at (5,3) size 146x16 + LayoutBlockFlow {DIV} at (0,0) size 131x16 + LayoutText {#text} at (0,0) size 0x0 +layer at (11,33) size 94x11 + LayoutBlockFlow {DIV} at (0,0) size 94x11 + LayoutText {#text} at (0,0) size 18x11 + text run at (0,0) width 18: "mini" +layer at (126,31) size 113x13 + LayoutBlockFlow {DIV} at (0,0) size 113x13 + LayoutText {#text} at (0,0) size 27x13 + text run at (0,0) width 27: "small" +layer at (264,29) size 131x16 + LayoutBlockFlow {DIV} at (0,0) size 131x16 + LayoutText {#text} at (0,0) size 44x16 + text run at (0,0) width 44: "regular" +layer at (106,34) size 9x9 transparent + LayoutBlockFlow {DIV} at (95,1) size 9x9 +layer at (240,32) size 11x11 transparent + LayoutBlockFlow {DIV} at (114,1) size 11x11 +layer at (396,30) size 14x14 transparent + LayoutBlockFlow {DIV} at (132,1) size 14x14
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png deleted file mode 100644 index cd7646b3..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt deleted file mode 100644 index 5e922d89..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutText {#text} at (0,0) size 533x18 - text run at (0,0) width 533: "This tests that we don't honor line-height for controls that have restricted font size. " - LayoutBR {BR} at (0,0) size 0x0 - LayoutMenuList {SELECT} at (0,19) size 299x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 299x18 - LayoutText (anonymous) at (8,2) size 268x13 - text run at (8,2) width 268: "This text should be centered vertically in the button" - LayoutText {#text} at (299,18) size 4x18 - text run at (299,18) width 4: " " - LayoutBR {BR} at (0,0) size 0x0 - LayoutButton {INPUT} at (0,38) size 283.41x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 267.41x13 - LayoutText {#text} at (0,0) size 268x13 - text run at (0,0) width 268: "This text should be centered vertically in the button" - LayoutText {#text} at (283,37) size 5x18 - text run at (283,37) width 5: " " - LayoutBR {BR} at (0,0) size 0x0 - LayoutTextControl {INPUT} at (0,56) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 0x0 -layer at (12,67) size 113x13 scrollWidth 268 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 268x13 - text run at (0,0) width 268: "This text should be centered vertically in the button" -layer at (126,68) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png index bd877ca7..87229435 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt deleted file mode 100644 index 54b6e32..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt +++ /dev/null
@@ -1,106 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x576 - LayoutBlockFlow (anonymous) at (0,0) size 784x18 - LayoutText {#text} at (0,0) size 781x18 - text run at (0,0) width 781: "This tests the height attribute of form elements. The only element that should honour this value is the Image type of input." - LayoutBlockFlow {FORM} at (0,18) size 784x229 - LayoutText {#text} at (0,0) size 37x18 - text run at (0,0) width 37: "input " - LayoutTextControl {INPUT} at (36.89,0) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (167,0) size 5x18 - text run at (167,0) width 5: " " - LayoutBR {BR} at (171,14) size 1x0 - LayoutText {#text} at (0,19) size 28x18 - text run at (0,19) width 28: "text " - LayoutTextControl {INPUT} at (27.98,19) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (158,19) size 5x18 - text run at (158,19) width 5: " " - LayoutBR {BR} at (162,33) size 1x0 - LayoutText {#text} at (0,38) size 66x18 - text run at (0,38) width 66: "checkbox " - LayoutBlockFlow {INPUT} at (68.19,42) size 12x12 - LayoutText {#text} at (83,38) size 5x18 - text run at (83,38) width 5: " " - LayoutBR {BR} at (87,52) size 1x0 - LayoutText {#text} at (0,57) size 25x18 - text run at (0,57) width 25: "file " - LayoutFileUploadControl {INPUT} at (24.44,58) size 236x18 "No file chosen" - LayoutButton {INPUT} at (0,0) size 76.61x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 60.61x13 - LayoutText {#text} at (0,0) size 61x13 - text run at (0,0) width 61: "Choose File" - LayoutText {#text} at (260,57) size 5x18 - text run at (260,57) width 5: " " - LayoutBR {BR} at (264,71) size 1x0 - LayoutText {#text} at (0,76) size 44x18 - text run at (0,76) width 44: "image " - LayoutImage {INPUT} at (43.09,89) size 10x1 - LayoutText {#text} at (53,76) size 5x18 - text run at (53,76) width 5: " " - LayoutBR {BR} at (57,90) size 1x0 - LayoutText {#text} at (0,94) size 37x18 - text run at (0,94) width 37: "radio " - LayoutBlockFlow {INPUT} at (39.77,97) size 12x13 - LayoutText {#text} at (54,94) size 5x18 - text run at (54,94) width 5: " " - LayoutBR {BR} at (58,108) size 1x0 - LayoutText {#text} at (0,116) size 40x18 - text run at (0,116) width 40: "range " - LayoutSlider {INPUT} at (41.53,115) size 129x15 [color=#909090] [bgcolor=#FFFFFF] - LayoutFlexibleBox {DIV} at (0,0) size 129x15 - LayoutBlockFlow {DIV} at (0,0) size 129x15 - LayoutBlockFlow {DIV} at (57,0) size 15x15 - LayoutText {#text} at (172,116) size 5x18 - text run at (172,116) width 5: " " - LayoutBR {BR} at (176,130) size 1x0 - LayoutText {#text} at (0,134) size 35x18 - text run at (0,134) width 35: "reset " - LayoutButton {INPUT} at (34.20,135) size 45.36x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 29.36x13 - LayoutText {#text} at (0,0) size 30x13 - text run at (0,0) width 30: "Reset" - LayoutText {#text} at (79,134) size 5x18 - text run at (79,134) width 5: " " - LayoutBR {BR} at (83,148) size 1x0 - LayoutText {#text} at (0,153) size 48x18 - text run at (0,153) width 48: "submit " - LayoutButton {INPUT} at (47.56,154) size 52.47x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 36.47x13 - LayoutText {#text} at (0,0) size 37x13 - text run at (0,0) width 37: "Submit" - LayoutText {#text} at (100,153) size 5x18 - text run at (100,153) width 5: " " - LayoutBR {BR} at (104,167) size 1x0 - LayoutText {#text} at (0,172) size 51x18 - text run at (0,172) width 51: "isindex " - LayoutTextControl {INPUT} at (50.22,172) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (181,172) size 5x18 - text run at (181,172) width 5: " " - LayoutBR {BR} at (185,186) size 1x0 - LayoutText {#text} at (0,191) size 65x18 - text run at (0,191) width 65: "password " - LayoutTextControl {INPUT} at (64.44,191) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (195,191) size 5x18 - text run at (195,191) width 5: " " - LayoutBR {BR} at (199,205) size 1x0 - LayoutText {#text} at (0,210) size 45x18 - text run at (0,210) width 45: "search " - LayoutTextControl {INPUT} at (44.86,210) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 0x0 -layer at (48,29) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (39,48) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (61,201) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (75,220) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (57,239) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (171,240) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png deleted file mode 100644 index 68da93f71..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt deleted file mode 100644 index 5b3127a..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt +++ /dev/null
@@ -1,180 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutTextControl {INPUT} at (0,0) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (133,0) size 4x18 - text run at (133,0) width 4: " " - LayoutBR {BR} at (137,14) size 0x0 - LayoutTextControl {INPUT} at (0,19) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (71,19) size 4x18 - text run at (71,19) width 4: " " - LayoutTextControl {INPUT} at (75,19) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (146,19) size 4x18 - text run at (146,19) width 4: " " - LayoutTextControl {INPUT} at (150,19) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (281,19) size 4x18 - text run at (281,19) width 4: " " - LayoutBR {BR} at (285,33) size 0x0 - LayoutTextControl {INPUT} at (0,38) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (12,0) size 113x13 - LayoutBR {BR} at (133,52) size 0x0 - LayoutTextControl {INPUT} at (0,57) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutBR {BR} at (133,71) size 0x0 - LayoutBR {BR} at (141,108) size 0x0 - LayoutTextControl {INPUT} at (0,108) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutBR {BR} at (131,122) size 0x0 - LayoutBR {BR} at (141,186) size 0x0 - LayoutTextControl {INPUT} at (5,191) size 179x30 [bgcolor=#FFFFFF] [border: (5px solid #000000)] - LayoutBR {BR} at (189,212) size 0x0 - LayoutTextControl {INPUT} at (0,226) size 131x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,232) size 4x18 - text run at (131,232) width 4: " " - LayoutTextControl {INPUT} at (135,226) size 131x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (266,232) size 4x18 - text run at (266,232) width 4: " " - LayoutTextControl {INPUT} at (270,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (401,232) size 4x18 - text run at (401,232) width 4: " " - LayoutTextControl {INPUT} at (405,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (536,232) size 4x18 - text run at (536,232) width 4: " " - LayoutTextControl {INPUT} at (540,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (671,232) size 4x18 - text run at (671,232) width 4: " " - LayoutBR {BR} at (0,0) size 0x0 - LayoutTextControl {INPUT} at (0,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,257) size 4x18 - text run at (131,257) width 4: " " - LayoutTextControl {INPUT} at (135,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (266,257) size 4x18 - text run at (266,257) width 4: " " - LayoutTextControl {INPUT} at (270,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (401,257) size 4x18 - text run at (401,257) width 4: " " - LayoutBR {BR} at (405,271) size 0x0 - LayoutBR {BR} at (131,304) size 0x0 -layer at (12,11) size 113x13 - LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (12,11) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (11,30) size 65x13 - LayoutBlockFlow {DIV} at (3,3) size 65x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (11,30) size 65x13 - LayoutBlockFlow {DIV} at (3,3) size 65x13 -layer at (86,30) size 65x13 - LayoutBlockFlow {DIV} at (3,3) size 65x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (86,30) size 65x13 - LayoutBlockFlow {DIV} at (3,3) size 65x13 -layer at (161,30) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 95x13 - text run at (0,0) width 95: "\x{65E5}\x{672C}\x{8A9E}placeholder" -layer at (161,30) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (24,49) size 113x13 - LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] - LayoutText {#text} at (52,0) size 61x13 - text run at (52,0) width 61: "placeholder" -layer at (24,49) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (12,68) size 113x13 - LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (12,68) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (8,84) size 141x32 clip at (9,85) size 139x30 - LayoutTextControl {TEXTAREA} at (0,76) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)] - LayoutBlockFlow {DIV} at (3,3) size 135x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" - LayoutBlockFlow {DIV} at (3,3) size 135x13 -layer at (11,119) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (11,119) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (8,149) size 141x45 clip at (9,150) size 139x43 - LayoutTextControl {TEXTAREA} at (0,141) size 141x45 [bgcolor=#FFFFFF] [border: (1px solid #000000)] - LayoutBlockFlow {DIV} at (3,16) size 135x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" - LayoutBlockFlow {DIV} at (3,16) size 135x13 -layer at (19,205) size 167x18 - LayoutBlockFlow {DIV} at (6,6) size 167x18 [color=#757575] - LayoutText {#text} at (0,0) size 84x18 - text run at (0,0) width 84: "placeholder" -layer at (19,205) size 167x18 - LayoutBlockFlow {DIV} at (6,6) size 167x18 -layer at (11,237) size 125x25 - LayoutBlockFlow {DIV} at (3,3) size 125x25 - LayoutText {#text} at (0,6) size 29x13 - text run at (0,6) width 29: "Value" -layer at (146,243) size 125x13 - LayoutBlockFlow {DIV} at (3,9) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (146,237) size 125x25 - LayoutBlockFlow {DIV} at (3,3) size 125x25 -layer at (281,243) size 125x13 - LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (281,243) size 125x13 - LayoutBlockFlow {DIV} at (3,6) size 125x13 -layer at (416,243) size 125x13 - LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (416,237) size 125x25 - LayoutBlockFlow {DIV} at (3,0) size 125x25 -layer at (551,243) size 125x13 - LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (551,243) size 125x13 - LayoutBlockFlow {DIV} at (3,6) size 125x13 -layer at (11,268) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (48,0) size 29x13 - text run at (48,0) width 29: "Value" -layer at (146,268) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (31,0) size 62x13 - text run at (31,0) width 62: "placeholder" -layer at (146,268) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (281,268) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (31,0) size 62x13 - text run at (31,0) width 62: "placeholder" -layer at (281,268) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (126,12) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (12,50) size 11x11 transparent - LayoutBlockFlow {DIV} at (0,1) size 11x11 -layer at (126,69) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (8,284) size 131x33 clip at (10,286) size 127x29 - LayoutTextControl {INPUT} at (0,276) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] -layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13 - LayoutBlockFlow {DIV} at (3,17) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 62x13 - text run at (0,0) width 62: "placeholder" -layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13 - LayoutBlockFlow {DIV} at (3,17) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png deleted file mode 100644 index acf9689..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt deleted file mode 100644 index 750d3de..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt +++ /dev/null
@@ -1,201 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x365 - LayoutBlockFlow {HTML} at (0,0) size 800x365 - LayoutBlockFlow {BODY} at (8,8) size 784x349 - LayoutBlockFlow (anonymous) at (0,0) size 784x83 - LayoutTextControl {INPUT} at (4,4) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (141,4) size 4x18 - text run at (141,4) width 4: " " - LayoutTextControl {INPUT} at (149,4) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutBlockFlow {DIV} at (114,1) size 11x11 - LayoutBR {BR} at (286,4) size 0x18 - LayoutTextControl {INPUT} at (4,31) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (141,31) size 4x18 - text run at (141,31) width 4: " " - LayoutTextControl {INPUT} at (149,31) size 133x19 [color=#545454] [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (286,31) size 4x18 - text run at (286,31) width 4: " " - LayoutBR {BR} at (290,31) size 0x18 - LayoutTextControl {INPUT} at (4,58) size 133x21 [bgcolor=#FFFFFF] [border: (3px solid #00FF00)] - LayoutFlexibleBox {DIV} at (4,4) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (141,59) size 4x18 - text run at (141,59) width 4: " " - LayoutTextControl {INPUT} at (149,59) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (3,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (284,59) size 4x18 - text run at (284,59) width 4: " " - LayoutBR {BR} at (288,59) size 0x18 - LayoutBlockFlow {DIV} at (0,83) size 163x45 [bgcolor=#888888] - LayoutTextControl {INPUT} at (11,9) size 133x19 [bgcolor=#00FF00] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (3,3) size 127x13 - LayoutBlockFlow {DIV} at (0,0) size 115x13 - LayoutText {#text} at (0,0) size 0x0 - LayoutBlockFlow (anonymous) at (0,128) size 784x221 - LayoutTextControl {INPUT} at (4,4) size 131x19 [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (3,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (139,4) size 4x18 - text run at (139,4) width 4: " " - LayoutBR {BR} at (143,4) size 0x18 - LayoutTextControl {INPUT} at (4,31) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (3,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (139,31) size 4x18 - text run at (139,31) width 4: " " - LayoutBR {BR} at (143,31) size 0x18 - LayoutTextControl {INPUT} at (4,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (5,3) size 146x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (164,60) size 4x18 - text run at (164,60) width 4: " " - LayoutTextControl {INPUT} at (172,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (5,3) size 146x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (332,60) size 4x18 - text run at (332,60) width 4: " " - LayoutTextControl {INPUT} at (340,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (5,3) size 146x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (500,60) size 4x18 - text run at (500,60) width 4: " " - LayoutBR {BR} at (504,60) size 0x18 - LayoutTextControl {INPUT} at (6,98.50) size 196x28 [bgcolor=#FFFFFF] [border: (3px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4.50,4.50) size 187x19 - LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (208,105) size 4x18 - text run at (208,105) width 4: " " - LayoutTextControl {INPUT} at (220,92) size 242x38 [bgcolor=#FFFFFF] [border: (4px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (6,6) size 230x26 - LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (470,105) size 4x18 - text run at (470,105) width 4: " " - LayoutBR {BR} at (474,105) size 0x18 - LayoutTextControl {INPUT} at (6,152.50) size 196x28 [bgcolor=#FFFFFF] [border: (3px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4.50,4.50) size 187x19 - LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (208,159) size 4x18 - text run at (208,159) width 4: " " - LayoutTextControl {INPUT} at (220,146) size 242x38 [bgcolor=#FFFFFF] [border: (4px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (6,6) size 230x26 - LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (470,159) size 4x18 - text run at (470,159) width 4: " " - LayoutBR {BR} at (474,159) size 0x18 - LayoutTextControl {INPUT} at (4,196) size 166x21 [bgcolor=#FFFFFF] [border: (1px solid #BDC7D8)] - LayoutFlexibleBox {DIV} at (18,4) size 144x13 - LayoutBlockFlow {DIV} at (0,0) size 132x13 - LayoutText {#text} at (0,0) size 0x0 -layer at (16,15) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (161,15) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (16,42) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (161,42) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (16,70) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (160,70) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (22,103) size 115x13 - LayoutBlockFlow {DIV} at (0,0) size 115x13 - LayoutText {#text} at (0,0) size 59x13 - text run at (0,0) width 59: "default text" -layer at (15,143) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (15,170) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 17x13 - text run at (0,0) width 17: "foo" -layer at (17,197) size 131x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 20x16 - text run at (0,0) width 20: "foo" -layer at (185,197) size 131x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 20x16 - text run at (0,0) width 20: "foo" -layer at (353,197) size 131x16 - LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 20x16 - text run at (0,0) width 20: "foo" -layer at (19,239) size 170x19 backgroundClip at (19,239) size 169x19 clip at (19,239) size 169x19 - LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (0,0) size 26x19 - text run at (0,0) width 26: "foo" -layer at (234,234) size 206x26 - LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (0,0) size 31x26 - text run at (0,0) width 31: "foo" -layer at (19,293) size 170x19 backgroundClip at (19,293) size 169x19 clip at (19,293) size 169x19 - LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (0,0) size 26x19 - text run at (0,0) width 26: "foo" -layer at (234,288) size 206x26 - LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (0,0) size 31x26 - text run at (0,0) width 31: "foo" -layer at (30,336) size 132x13 - LayoutBlockFlow {DIV} at (18,4) size 132x13 [color=#757575] - LayoutText {#text} at (0,0) size 92x13 - text run at (0,0) width 92: "Search for Events" -layer at (30,336) size 132x13 - LayoutBlockFlow {DIV} at (0,0) size 132x13 -layer at (130,16) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (130,43) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (275,43) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (130,71) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (274,71) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (138,104) size 11x11 transparent - LayoutBlockFlow {DIV} at (116,1) size 11x11 -layer at (129,144) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (129,171) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (149,198) size 14x14 transparent - LayoutBlockFlow {DIV} at (132,1) size 14x14 -layer at (317,198) size 14x14 transparent - LayoutBlockFlow {DIV} at (132,1) size 14x14 -layer at (485,198) size 14x14 transparent - LayoutBlockFlow {DIV} at (132,1) size 14x14 -layer at (190,241) size 16x16 transparent - LayoutBlockFlow {DIV} at (171,1.50) size 16x16 -layer at (442,236) size 22x22 transparent - LayoutBlockFlow {DIV} at (208,2) size 22x22 -layer at (190,295) size 16x16 transparent - LayoutBlockFlow {DIV} at (171,1.50) size 16x16 -layer at (442,290) size 22x22 transparent - LayoutBlockFlow {DIV} at (208,2) size 22x22 -layer at (163,337) size 11x11 transparent - LayoutBlockFlow {DIV} at (133,1) size 11x11 -caret: position 0 of child 0 {#text} of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 10 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png deleted file mode 100644 index 37620a2..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png deleted file mode 100644 index 40ca375..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png deleted file mode 100644 index d6b2dcc..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png index 0e1641f..e3ac520e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt index 07653909..9ec60640 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt
@@ -6,27 +6,27 @@ LayoutText {#text} at (0,0) size 533x18 text run at (0,0) width 533: "This tests that we don't honor line-height for controls that have restricted font size. " LayoutBR {BR} at (0,0) size 0x0 - LayoutMenuList {SELECT} at (0,19) size 299x18 [bgcolor=#F8F8F8] - LayoutBlockFlow (anonymous) at (0,0) size 299x18 - LayoutText (anonymous) at (8,2) size 268x13 - text run at (8,2) width 268: "This text should be centered vertically in the button" - LayoutText {#text} at (299,18) size 4x18 - text run at (299,18) width 4: " " + LayoutMenuList {SELECT} at (0,19) size 302x18 [bgcolor=#F8F8F8] + LayoutBlockFlow (anonymous) at (0,0) size 302x18 + LayoutText (anonymous) at (8,2) size 271x13 + text run at (8,2) width 271: "This text should be centered vertically in the button" + LayoutText {#text} at (302,18) size 4x18 + text run at (302,18) width 4: " " LayoutBR {BR} at (0,0) size 0x0 - LayoutButton {INPUT} at (0,38) size 283.92x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 267.92x13 - LayoutText {#text} at (0,0) size 268x13 - text run at (0,0) width 268: "This text should be centered vertically in the button" - LayoutText {#text} at (283,37) size 5x18 - text run at (283,37) width 5: " " + LayoutButton {INPUT} at (0,38) size 286.83x18 [bgcolor=#FFFFFF] + LayoutBlockFlow (anonymous) at (8,2) size 270.83x13 + LayoutText {#text} at (0,0) size 271x13 + text run at (0,0) width 271: "This text should be centered vertically in the button" + LayoutText {#text} at (286,37) size 5x18 + text run at (286,37) width 5: " " LayoutBR {BR} at (0,0) size 0x0 LayoutTextControl {INPUT} at (0,56) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] LayoutFlexibleBox {DIV} at (4,3) size 125x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 LayoutText {#text} at (0,0) size 0x0 -layer at (12,67) size 113x13 scrollWidth 269 +layer at (12,67) size 113x13 scrollWidth 272 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 268x13 - text run at (0,0) width 268: "This text should be centered vertically in the button" + LayoutText {#text} at (0,0) size 271x13 + text run at (0,0) width 271: "This text should be centered vertically in the button" layer at (126,68) size 11x11 transparent LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png index e03080d..efbf395 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt index 950df077..eec843f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt
@@ -27,14 +27,14 @@ LayoutBR {BR} at (87,52) size 1x0 LayoutText {#text} at (0,57) size 25x18 text run at (0,57) width 25: "file " - LayoutFileUploadControl {INPUT} at (24.44,58) size 236x18 "No file chosen" - LayoutButton {INPUT} at (0,0) size 76.61x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 60.61x13 - LayoutText {#text} at (0,0) size 61x13 - text run at (0,0) width 61: "Choose File" - LayoutText {#text} at (260,57) size 5x18 - text run at (260,57) width 5: " " - LayoutBR {BR} at (264,71) size 1x0 + LayoutFileUploadControl {INPUT} at (24.44,58) size 238x18 "No file chosen" + LayoutButton {INPUT} at (0,0) size 77.33x18 [bgcolor=#FFFFFF] + LayoutBlockFlow (anonymous) at (8,2) size 61.33x13 + LayoutText {#text} at (0,0) size 62x13 + text run at (0,0) width 62: "Choose File" + LayoutText {#text} at (262,57) size 5x18 + text run at (262,57) width 5: " " + LayoutBR {BR} at (266,71) size 1x0 LayoutText {#text} at (0,76) size 44x18 text run at (0,76) width 44: "image " LayoutImage {INPUT} at (43.09,89) size 10x1 @@ -58,8 +58,8 @@ LayoutBR {BR} at (176,130) size 1x0 LayoutText {#text} at (0,134) size 35x18 text run at (0,134) width 35: "reset " - LayoutButton {INPUT} at (34.20,135) size 45.52x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 29.52x13 + LayoutButton {INPUT} at (34.20,135) size 45.67x18 [bgcolor=#FFFFFF] + LayoutBlockFlow (anonymous) at (8,2) size 29.67x13 LayoutText {#text} at (0,0) size 30x13 text run at (0,0) width 30: "Reset" LayoutText {#text} at (79,134) size 5x18 @@ -67,8 +67,8 @@ LayoutBR {BR} at (83,148) size 1x0 LayoutText {#text} at (0,153) size 48x18 text run at (0,153) width 48: "submit " - LayoutButton {INPUT} at (47.56,154) size 52.47x18 [bgcolor=#FFFFFF] - LayoutBlockFlow (anonymous) at (8,2) size 36.47x13 + LayoutButton {INPUT} at (47.56,154) size 52.86x18 [bgcolor=#FFFFFF] + LayoutBlockFlow (anonymous) at (8,2) size 36.86x13 LayoutText {#text} at (0,0) size 37x13 text run at (0,0) width 37: "Submit" LayoutText {#text} at (100,153) size 5x18
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png index b04157f5..e57a131f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt index 04ae42ff..d3a59ba 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
@@ -80,8 +80,8 @@ LayoutBlockFlow {DIV} at (3,3) size 65x13 layer at (161,30) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 95x13 - text run at (0,0) width 95: "\x{65E5}\x{672C}\x{8A9E}placeholder" + LayoutText {#text} at (0,0) size 96x13 + text run at (0,0) width 96: "\x{65E5}\x{672C}\x{8A9E}placeholder" layer at (161,30) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 layer at (24,49) size 113x13 @@ -116,8 +116,8 @@ LayoutBlockFlow {DIV} at (3,16) size 135x13 layer at (19,205) size 167x18 LayoutBlockFlow {DIV} at (6,6) size 167x18 [color=#757575] - LayoutText {#text} at (0,0) size 84x18 - text run at (0,0) width 84: "placeholder" + LayoutText {#text} at (0,0) size 81x18 + text run at (0,0) width 81: "placeholder" layer at (19,205) size 167x18 LayoutBlockFlow {DIV} at (6,6) size 167x18 layer at (11,237) size 125x25 @@ -154,14 +154,14 @@ text run at (48,0) width 29: "Value" layer at (146,268) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (31,0) size 62x13 - text run at (31,0) width 62: "placeholder" + LayoutText {#text} at (31,0) size 63x13 + text run at (31,0) width 63: "placeholder" layer at (146,268) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 layer at (281,268) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (31,0) size 62x13 - text run at (31,0) width 62: "placeholder" + LayoutText {#text} at (31,0) size 63x13 + text run at (31,0) width 63: "placeholder" layer at (281,268) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 layer at (126,12) size 11x11 transparent
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png index c5adc19d..ab528ab 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt index a39ced5..081b3f831 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt
@@ -134,32 +134,32 @@ text run at (0,0) width 17: "foo" layer at (17,197) size 131x16 LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 21x16 - text run at (0,0) width 21: "foo" + LayoutText {#text} at (0,0) size 20x16 + text run at (0,0) width 20: "foo" layer at (185,197) size 131x16 LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 21x16 - text run at (0,0) width 21: "foo" + LayoutText {#text} at (0,0) size 20x16 + text run at (0,0) width 20: "foo" layer at (353,197) size 131x16 LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 21x16 - text run at (0,0) width 21: "foo" + LayoutText {#text} at (0,0) size 20x16 + text run at (0,0) width 20: "foo" layer at (19,239) size 170x19 backgroundClip at (19,239) size 169x19 clip at (19,239) size 169x19 LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (0,0) size 26x19 - text run at (0,0) width 26: "foo" + LayoutText {#text} at (0,0) size 25x19 + text run at (0,0) width 25: "foo" layer at (234,234) size 206x26 LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (0,0) size 31x26 - text run at (0,0) width 31: "foo" + LayoutText {#text} at (0,0) size 32x26 + text run at (0,0) width 32: "foo" layer at (19,293) size 170x19 backgroundClip at (19,293) size 169x19 clip at (19,293) size 169x19 LayoutBlockFlow {DIV} at (0,0) size 169.50x19 - LayoutText {#text} at (0,0) size 26x19 - text run at (0,0) width 26: "foo" + LayoutText {#text} at (0,0) size 25x19 + text run at (0,0) width 25: "foo" layer at (234,288) size 206x26 LayoutBlockFlow {DIV} at (0,0) size 206x26 - LayoutText {#text} at (0,0) size 31x26 - text run at (0,0) width 31: "foo" + LayoutText {#text} at (0,0) size 32x26 + text run at (0,0) width 32: "foo" layer at (30,336) size 132x13 LayoutBlockFlow {DIV} at (18,4) size 132x13 [color=#757575] LayoutText {#text} at (0,0) size 92x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png index 467b065..318beb4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png index 62b30cd..830368ac 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt index 16f973e..61c6801 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt
@@ -35,20 +35,20 @@ LayoutBlockFlow {P} at (0,107) size 784x18 LayoutText {#text} at (0,0) size 37x18 text run at (0,0) width 37: "PASS" -layer at (24,45) size 113x13 scrollX 1.00 scrollWidth 115 +layer at (24,45) size 113x13 scrollX 2.00 scrollWidth 115 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (-1,0) size 115x13 - text run at (-1,0) width 21 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" - text run at (19,0) width 9: "B" - text run at (27,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " + LayoutText {#text} at (-2,0) size 116x13 + text run at (-2,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" + text run at (19,0) width 8: "B" + text run at (26,0) width 44 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " text run at (69,0) width 8: "A" text run at (76,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} " layer at (24,64) size 173x13 LayoutBlockFlow {DIV} at (0,0) size 173x13 - LayoutText {#text} at (58,0) size 115x13 - text run at (58,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" - text run at (79,0) width 9: "B" - text run at (87,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " + LayoutText {#text} at (57,0) size 116x13 + text run at (57,0) width 23 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}" + text run at (79,0) width 8: "B" + text run at (86,0) width 44 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} " text run at (129,0) width 8: "A" text run at (136,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} " layer at (24,83) size 113x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png index a912409..89fc5d0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt index 9df5ced..c5ba5cc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt
@@ -22,16 +22,16 @@ LayoutText {#text} at (0,0) size 0x0 layer at (11,33) size 94x11 LayoutBlockFlow {DIV} at (0,0) size 94x11 - LayoutText {#text} at (0,0) size 18x11 - text run at (0,0) width 18: "mini" + LayoutText {#text} at (0,0) size 19x11 + text run at (0,0) width 19: "mini" layer at (126,31) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 27x13 - text run at (0,0) width 27: "small" + LayoutText {#text} at (0,0) size 28x13 + text run at (0,0) width 28: "small" layer at (264,29) size 131x16 LayoutBlockFlow {DIV} at (0,0) size 131x16 - LayoutText {#text} at (0,0) size 44x16 - text run at (0,0) width 44: "regular" + LayoutText {#text} at (0,0) size 43x16 + text run at (0,0) width 43: "regular" layer at (106,34) size 9x9 transparent LayoutBlockFlow {DIV} at (95,1) size 9x9 layer at (240,32) size 11x11 transparent
diff --git a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html index 8451acf..75342ce 100644 --- a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html +++ b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html
@@ -1,5 +1,6 @@ <html> <head> +<script src="../../resources/gc.js"></script> <script src="resources/database-common.js"></script> <script src="multiple-databases-garbage-collection.js"></script> <body onload="setupAndRunTest();">
diff --git a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js index ba47b0b..ebd7aa7 100644 --- a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js +++ b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js
@@ -1,15 +1,3 @@ -function GC() -{ - // Force GC. - if (window.GCController) - GCController.collectAll(); - else { - for (var i = 0; i < 10000; ++i) { - ({ }); - } - } -} - // Variable for the database that will never be forgotten var persistentDB = 0; // Variable for the forgotten database @@ -32,12 +20,12 @@ }, function(err) { log("Forgotten Database Transaction Errored - " + err); forgottenDB = 0; - GC(); + gc(); checkCompletion(); }, function() { log("Forgotten Database Transaction Complete"); forgottenDB = 0; - GC(); + gc(); checkCompletion(); });
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py index 516ba12..c228acf 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
@@ -29,13 +29,12 @@ import itertools import logging import os +import posixpath import re import sys import threading import time -from multiprocessing.pool import ThreadPool - from webkitpy.common import exit_codes from webkitpy.common.system.executive import ScriptError from webkitpy.layout_tests.breakpad.dump_reader_multipart import DumpReaderAndroid @@ -218,9 +217,6 @@ def library_name(self): return 'libcontent_shell_content_view.so' - def additional_resources(self): - return [] - def command_line_file(self): return '/data/local/tmp/content-shell-command-line' @@ -374,50 +370,131 @@ return self._check_devices(printer) def _check_devices(self, printer): - # Printer objects aren't threadsafe, so we need to protect calls to them. - lock = threading.Lock() - pool = None # Push the executables and other files to the devices; doing this now # means we can do this in parallel in the manager process and not mix # this in with starting and stopping workers. - def setup_device(worker_number): - d = self.create_driver(worker_number) - serial = d._device.serial # pylint: disable=protected-access - def log_safely(msg, throttled=True): - if throttled: - callback = printer.write_throttled_update - else: - callback = printer.write_update - with lock: - callback('[%s] %s' % (serial, msg)) + lock = threading.Lock() + def log_safely(msg, throttled=True): + if throttled: + callback = printer.write_throttled_update + else: + callback = printer.write_update + with lock: + callback('%s' % msg) + + def _setup_device_impl(device): log_safely('preparing device', throttled=False) + + if self._devices.is_device_prepared(device.serial): + return + + device.EnableRoot() + perf_control.PerfControl(device).SetPerfProfilingMode() + + # Required by webkit_support::GetWebKitRootDirFilePath(). + # Other directories will be created automatically by adb push. + device.RunShellCommand( + ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'], + check_return=True) + + # Allow the test driver to get full read and write access to the directory on the device, + # as well as for the FIFOs. We'll need a world writable directory. + device.RunShellCommand( + ['mkdir', '-p', self._driver_details.device_directory()], + check_return=True) + + # Make sure that the disk cache on the device resets to a clean state. + device.RunShellCommand( + ['rm', '-rf', self._driver_details.device_cache_directory()], + check_return=True) + + device.EnableRoot() + perf_control.PerfControl(device).SetPerfProfilingMode() + + # Required by webkit_support::GetWebKitRootDirFilePath(). + # Other directories will be created automatically by adb push. + device.RunShellCommand( + ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'], + check_return=True) + + # Allow the test driver to get full read and write access to the directory on the device, + # as well as for the FIFOs. We'll need a world writable directory. + device.RunShellCommand( + ['mkdir', '-p', self._driver_details.device_directory()], + check_return=True) + + # Make sure that the disk cache on the device resets to a clean state. + device.RunShellCommand( + ['rm', '-rf', self._driver_details.device_cache_directory()], + check_return=True) + + device_path = lambda *p: posixpath.join( + self._driver_details.device_directory(), *p) + + device.Install(self._path_to_driver()) + + # Build up a list of what we want to push, including: + host_device_tuples = [] + + # - the custom font files + host_device_tuples.append( + (self._build_path('android_main_fonts.xml'), + device_path('android_main_fonts.xml'))) + host_device_tuples.append( + (self._build_path('android_fallback_fonts.xml'), + device_path('android_fallback_fonts.xml'))) + host_device_tuples.append( + (self._build_path('AHEM____.TTF'), + device_path('fonts', 'AHEM____.TTF'))) + for (host_dirs, font_file, _) in HOST_FONT_FILES: + for host_dir in host_dirs: + host_font_path = host_dir + font_file + if self._check_file_exists(host_font_path, '', more_logging=False): + host_device_tuples.append( + (host_font_path, + device_path('fonts', font_file))) + + # - the test resources + host_device_tuples.extend( + (self.host.filesystem.join(self.layout_tests_dir(), resource), + posixpath.join(DEVICE_LAYOUT_TESTS_DIR, resource)) + for resource in TEST_RESOURCES_TO_PUSH) + + # ... and then push them to the device. + device.PushChangedFiles(host_device_tuples) + + device.RunShellCommand( + ['mkdir', '-p', self._driver_details.device_fifo_directory()], + check_return=True) + + device.RunShellCommand( + ['chmod', '-R', '777', self._driver_details.device_directory()], + check_return=True) + device.RunShellCommand( + ['chmod', '-R', '777', self._driver_details.device_fifo_directory()], + check_return=True) + + # Mark this device as having been set up. + self._devices.set_device_prepared(device.serial) + + log_safely('device prepared', throttled=False) + + def setup_device(device): try: - d._setup_test(log_safely) - log_safely('device prepared', throttled=False) - except (ScriptError, driver.DeviceFailure) as error: + _setup_device_impl(device) + except (ScriptError, + driver.DeviceFailure, + device_errors.CommandFailedError, + device_errors.CommandTimeoutError, + device_errors.DeviceUnreachableError) as error: with lock: _log.warning('[%s] failed to prepare_device: %s', serial, error) - except KeyboardInterrupt: - if pool: - pool.terminate() - # FIXME: It would be nice if we knew how many workers we needed. - num_workers = self.default_child_processes() - num_child_processes = int(self.get_option('child_processes')) - if num_child_processes: - num_workers = min(num_workers, num_child_processes) - if num_workers > 1: - pool = ThreadPool(num_workers) - try: - pool.map(setup_device, range(num_workers)) - except KeyboardInterrupt: - pool.terminate() - raise - else: - setup_device(0) + devices = self._devices.usable_devices(self.host.executive) + device_utils.DeviceUtils.parallel(devices).pMap(setup_device) if not self._devices.prepared_devices(): _log.error('Could not prepare any devices for testing.') @@ -711,55 +788,6 @@ return symfs_path - def _push_data_if_needed(self, log_callback): - self._push_executable(log_callback) - self._push_fonts(log_callback) - self._push_test_resources(log_callback) - - def _setup_test(self, log_callback): - # FIXME: Move this routine and its subroutines off of the AndroidDriver - # class and onto some other helper class, so that we - # can initialize the device without needing to create a driver. - - if self._android_devices.is_device_prepared(self._device.serial): - return - - self._device.EnableRoot() - self._setup_performance() - - # Required by webkit_support::GetWebKitRootDirFilePath(). - # Other directories will be created automatically by adb push. - self._device.RunShellCommand( - ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'], - check_return=True) - - # Allow the test driver to get full read and write access to the directory on the device, - # as well as for the FIFOs. We'll need a world writable directory. - self._device.RunShellCommand( - ['mkdir', '-p', self._driver_details.device_directory()], - check_return=True) - - # Make sure that the disk cache on the device resets to a clean state. - self._device.RunShellCommand( - ['rm', '-rf', self._driver_details.device_cache_directory()], - check_return=True) - - self._push_data_if_needed(log_callback) - - self._device.RunShellCommand( - ['mkdir', '-p', self._driver_details.device_fifo_directory()], - check_return=True) - - self._device.RunShellCommand( - ['chmod', '-R', '777', self._driver_details.device_directory()], - check_return=True) - self._device.RunShellCommand( - ['chmod', '-R', '777', self._driver_details.device_fifo_directory()], - check_return=True) - - # Mark this device as having been set up. - self._android_devices.set_device_prepared(self._device.serial) - def _log_error(self, message): _log.error('[%s] %s', self._device.serial, message) @@ -774,45 +802,6 @@ self._device_failed = True raise driver.DeviceFailure('[%s] %s' % (self._device.serial, message)) - def _push_file_if_needed(self, host_file, device_file, log_callback): - basename = self._port.host.filesystem.basename(host_file) - log_callback('checking %s' % basename) - self._device.PushChangedFiles([(host_file, device_file)]) - - def _push_executable(self, log_callback): - for resource in self._driver_details.additional_resources(): - self._push_file_if_needed(self._port._build_path( - resource), self._driver_details.device_directory() + resource, log_callback) - - self._push_file_if_needed(self._port._build_path('android_main_fonts.xml'), - self._driver_details.device_directory() + 'android_main_fonts.xml', log_callback) - self._push_file_if_needed(self._port._build_path('android_fallback_fonts.xml'), - self._driver_details.device_directory() + 'android_fallback_fonts.xml', log_callback) - - try: - driver_host_path = self._port._path_to_driver() # pylint: disable=protected-access - log_callback('installing apk if necessary') - self._device.Install(driver_host_path) - except (device_errors.CommandFailedError, - device_errors.CommandTimeoutError, - device_errors.DeviceUnreachableError) as exc: - self._abort('Failed to install %s onto device: %s' % (driver_host_path, str(exc))) - - def _push_fonts(self, log_callback): - path_to_ahem_font = self._port._build_path('AHEM____.TTF') - self._push_file_if_needed(path_to_ahem_font, self._driver_details.device_fonts_directory() + 'AHEM____.TTF', log_callback) - for (host_dirs, font_file, _) in HOST_FONT_FILES: - for host_dir in host_dirs: - host_font_path = host_dir + font_file - if self._port._check_file_exists(host_font_path, '', more_logging=False): - self._push_file_if_needed( - host_font_path, self._driver_details.device_fonts_directory() + font_file, log_callback) - - def _push_test_resources(self, log_callback): - for resource in TEST_RESOURCES_TO_PUSH: - self._push_file_if_needed(self._port.layout_tests_dir() + '/' + resource, - DEVICE_LAYOUT_TESTS_DIR + resource, log_callback) - def _get_last_stacktrace(self): try: tombstones = self._device.RunShellCommand( @@ -854,10 +843,6 @@ def _get_logcat(self): return '\n'.join(self._device.adb.Logcat(dump=True, logcat_format='threadtime')) - def _setup_performance(self): - # Disable CPU scaling and drop ram cache to reduce noise in tests - perf_control.PerfControl(self._device).SetPerfProfilingMode() - def _teardown_performance(self): perf_control.PerfControl(self._device).SetDefaultPerfMode()
diff --git a/tools/code_coverage/OWNERS b/tools/code_coverage/OWNERS new file mode 100644 index 0000000..9fd85c05 --- /dev/null +++ b/tools/code_coverage/OWNERS
@@ -0,0 +1,3 @@ +liaoyuke@chromium.org +mmoroz@chromium.org +inferno@chromum.org
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py new file mode 100755 index 0000000..e6d245e --- /dev/null +++ b/tools/code_coverage/coverage.py
@@ -0,0 +1,470 @@ +#!/usr/bin/python +# Copyright 2017 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. + +"""Script to generate Clang source based code coverage report. + + NOTE: This script must be called from the root of checkout, and because it + requires building with gn arg "is_component_build=false", the build is not + compatible with sanitizer flags (such as "is_asan" and "is_msan") and flag + "optimize_for_fuzzing". + + Example usages: + python tools/code_coverage/coverage.py crypto_unittests url_unittests + -b out/Coverage -o out/report -c 'out/Coverage/crypto_unittests' + -c 'out/Coverage/url_unittests --gtest_filter=URLParser.PathURL' + # Generate code coverage report for crypto_unittests and url_unittests and + # all generated artifacts are stored in out/report. For url_unittests, only + # run test URLParser.PathURL. + + For more options, please refer to tools/coverage/coverage.py -h for help. +""" + +from __future__ import print_function + +import sys + +import argparse +import os +import subprocess +import threading +import urllib2 + +sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir, + os.path.pardir, 'tools', 'clang', 'scripts')) + +import update as clang_update + +# Absolute path to the root of the checkout. +SRC_ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), + os.path.pardir, os.path.pardir)) + +# Absolute path to the code coverage tools binary. +LLVM_BUILD_DIR = clang_update.LLVM_BUILD_DIR +LLVM_COV_PATH = os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-cov') +LLVM_PROFDATA_PATH = os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-profdata') + +# Build directory, the value is parsed from command line arguments. +BUILD_DIR = None + +# Output directory for generated artifacts, the value is parsed from command +# line arguemnts. +OUTPUT_DIR = None + +# Default number of jobs used to build when goma is configured and enabled. +DEFAULT_GOMA_JOBS = 100 + +# Name of the file extension for profraw data files. +PROFRAW_FILE_EXTENSION = 'profraw' + +# Name of the final profdata file, and this file needs to be passed to +# "llvm-cov" command in order to call "llvm-cov show" to inspect the +# line-by-line coverage of specific files. +PROFDATA_FILE_NAME = 'coverage.profdata' + +# Build arg required for generating code coverage data. +CLANG_COVERAGE_BUILD_ARG = 'use_clang_coverage' + +# A set of targets that depend on target "testing/gtest", this set is generated +# by 'gn refs "testing/gtest"', and it is lazily initialized when needed. +GTEST_TARGET_NAMES = None + + +# TODO(crbug.com/759794): remove this function once tools get included to +# Clang bundle: +# https://chromium-review.googlesource.com/c/chromium/src/+/688221 +def DownloadCoverageToolsIfNeeded(): + """Temporary solution to download llvm-profdata and llvm-cov tools.""" + def _GetRevisionFromStampFile(stamp_file_path): + """Returns a pair of revision number by reading the build stamp file. + + Args: + stamp_file_path: A path the build stamp file created by + tools/clang/scripts/update.py. + Returns: + A pair of integers represeting the main and sub revision respectively. + """ + if not os.path.exists(stamp_file_path): + return 0, 0 + + with open(stamp_file_path) as stamp_file: + revision_stamp_data = stamp_file.readline().strip().split('-') + return int(revision_stamp_data[0]), int(revision_stamp_data[1]) + + clang_revision, clang_sub_revision = _GetRevisionFromStampFile( + clang_update.STAMP_FILE) + + coverage_revision_stamp_file = os.path.join( + os.path.dirname(clang_update.STAMP_FILE), 'cr_coverage_revision') + coverage_revision, coverage_sub_revision = _GetRevisionFromStampFile( + coverage_revision_stamp_file) + + if (coverage_revision == clang_revision and + coverage_sub_revision == clang_sub_revision): + # LLVM coverage tools are up to date, bail out. + return clang_revision + + package_version = '%d-%d' % (clang_revision, clang_sub_revision) + coverage_tools_file = 'llvm-code-coverage-%s.tgz' % package_version + + # The code bellow follows the code from tools/clang/scripts/update.py. + if sys.platform == 'win32' or sys.platform == 'cygwin': + coverage_tools_url = clang_update.CDS_URL + '/Win/' + coverage_tools_file + elif sys.platform == 'darwin': + coverage_tools_url = clang_update.CDS_URL + '/Mac/' + coverage_tools_file + else: + assert sys.platform.startswith('linux') + coverage_tools_url = ( + clang_update.CDS_URL + '/Linux_x64/' + coverage_tools_file) + + try: + clang_update.DownloadAndUnpack(coverage_tools_url, + clang_update.LLVM_BUILD_DIR) + print('Coverage tools %s unpacked' % package_version) + with open(coverage_revision_stamp_file, 'w') as file_handle: + file_handle.write(package_version) + file_handle.write('\n') + except urllib2.URLError: + raise Exception( + 'Failed to download coverage tools: %s.' % coverage_tools_url) + + +def _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path): + """Generates per file line-by-line coverage in html using 'llvm-cov show'. + + For a file with absolute path /a/b/x.cc, a html report is generated as: + OUTPUT_DIR/coverage/a/b/x.cc.html. An index html file is also generated as: + OUTPUT_DIR/index.html. + + Args: + binary_paths: A list of paths to the instrumented binaries. + profdata_file_path: A path to the profdata file. + """ + print('Generating per file line by line code coverage in html') + + # llvm-cov show [options] -instr-profile PROFILE BIN [-object BIN,...] + # [[-object BIN]] [SOURCES] + # NOTE: For object files, the first one is specified as a positional argument, + # and the rest are specified as keyword argument. + subprocess_cmd = [LLVM_COV_PATH, 'show', '-format=html', + '-output-dir={}'.format(OUTPUT_DIR), + '-instr-profile={}'.format(profdata_file_path), + binary_paths[0]] + subprocess_cmd.extend(['-object=' + binary_path + for binary_path in binary_paths[1:]]) + + subprocess.check_call(subprocess_cmd) + + +def _CreateCoverageProfileDataForTargets(targets, commands, jobs_count=None): + """Builds and runs target to generate the coverage profile data. + + Args: + targets: A list of targets to build with coverage instrumentation. + commands: A list of commands used to run the targets. + jobs_count: Number of jobs to run in parallel for building. If None, a + default value is derived based on CPUs availability. + + Returns: + A relative path to the generated profdata file. + """ + _BuildTargets(targets, jobs_count) + profraw_file_paths = _GetProfileRawDataPathsByExecutingCommands(targets, + commands) + profdata_file_path = _CreateCoverageProfileDataFromProfRawData( + profraw_file_paths) + + return profdata_file_path + + +def _BuildTargets(targets, jobs_count): + """Builds target with Clang coverage instrumentation. + + This function requires current working directory to be the root of checkout. + + Args: + targets: A list of targets to build with coverage instrumentation. + jobs_count: Number of jobs to run in parallel for compilation. If None, a + default value is derived based on CPUs availability. + + + """ + def _IsGomaConfigured(): + """Returns True if goma is enabled in the gn build args. + + Returns: + A boolean indicates whether goma is configured for building or not. + """ + build_args = _ParseArgsGnFile() + return 'use_goma' in build_args and build_args['use_goma'] == 'true' + + print('Building %s' % str(targets)) + + if jobs_count is None and _IsGomaConfigured(): + jobs_count = DEFAULT_GOMA_JOBS + + subprocess_cmd = ['ninja', '-C', BUILD_DIR] + if jobs_count is not None: + subprocess_cmd.append('-j' + str(jobs_count)) + + subprocess_cmd.extend(targets) + subprocess.check_call(subprocess_cmd) + + +def _GetProfileRawDataPathsByExecutingCommands(targets, commands): + """Runs commands and returns the relative paths to the profraw data files. + + Args: + targets: A list of targets built with coverage instrumentation. + commands: A list of commands used to run the targets. + + Returns: + A list of relative paths to the generated profraw data files. + """ + # Remove existing profraw data files. + for file_or_dir in os.listdir(OUTPUT_DIR): + if file_or_dir.endswith(PROFRAW_FILE_EXTENSION): + os.remove(os.path.join(OUTPUT_DIR, file_or_dir)) + + # Run different test targets in parallel to generate profraw data files. + threads = [] + for target, command in zip(targets, commands): + thread = threading.Thread(target=_ExecuteCommand, args=(target, command)) + thread.start() + threads.append(thread) + for thread in threads: + thread.join() + + profraw_file_paths = [] + for file_or_dir in os.listdir(OUTPUT_DIR): + if file_or_dir.endswith(PROFRAW_FILE_EXTENSION): + profraw_file_paths.append(os.path.join(OUTPUT_DIR, file_or_dir)) + + # Assert one target/command generates at least one profraw data file. + for target in targets: + assert any(os.path.basename(profraw_file).startswith(target) for + profraw_file in profraw_file_paths), ('Running target: %s ' + 'failed to generate any ' + 'profraw data file, ' + 'please make sure the ' + 'binary exists and is ' + 'properly instrumented.' + % target) + + return profraw_file_paths + + +def _ExecuteCommand(target, command): + """Runs a single command and generates a profraw data file. + + Args: + target: A target built with coverage instrumentation. + command: A command used to run the target. + """ + if _IsTargetGTestTarget(target): + # This test argument is required and only required for gtest unit test + # targets because by default, they run tests in parallel, and that won't + # generated code coverage data correctly. + command += ' --test-launcher-jobs=1' + + expected_profraw_file_name = os.extsep.join([target, '%p', + PROFRAW_FILE_EXTENSION]) + expected_profraw_file_path = os.path.join(OUTPUT_DIR, + expected_profraw_file_name) + output_file_name = os.extsep.join([target + '_output', 'txt']) + output_file_path = os.path.join(OUTPUT_DIR, output_file_name) + + print('Running command: "%s", the output is redirected to "%s"' % + (command, output_file_path)) + output = subprocess.check_output(command.split(), + env={'LLVM_PROFILE_FILE': + expected_profraw_file_path}) + with open(output_file_path, 'w') as output_file: + output_file.write(output) + + +def _CreateCoverageProfileDataFromProfRawData(profraw_file_paths): + """Returns a relative path to the profdata file by merging profraw data files. + + Args: + profraw_file_paths: A list of relative paths to the profraw data files that + are to be merged. + + Returns: + A relative path to the generated profdata file. + + Raises: + CalledProcessError: An error occurred merging profraw data files. + """ + print('Creating the profile data file') + + profdata_file_path = os.path.join(OUTPUT_DIR, PROFDATA_FILE_NAME) + try: + subprocess_cmd = [LLVM_PROFDATA_PATH, 'merge', '-o', profdata_file_path, + '-sparse=true'] + subprocess_cmd.extend(profraw_file_paths) + subprocess.check_call(subprocess_cmd) + except subprocess.CalledProcessError as error: + print('Failed to merge profraw files to create profdata file') + raise error + + return profdata_file_path + + +def _GetBinaryPath(command): + """Returns a relative path to the binary to be run by the command. + + Args: + command: A command used to run a target. + + Returns: + A relative path to the binary. + """ + return command.split()[0] + + +def _IsTargetGTestTarget(target): + """Returns True if the target is a gtest target. + + Args: + target: A target built with coverage instrumentation. + + Returns: + A boolean value indicates whether the target is a gtest target. + """ + global GTEST_TARGET_NAMES + if GTEST_TARGET_NAMES is None: + output = subprocess.check_output(['gn', 'refs', BUILD_DIR, 'testing/gtest']) + list_of_gtest_targets = [gtest_target + for gtest_target in output.splitlines() + if gtest_target] + GTEST_TARGET_NAMES = set([gtest_target.split(':')[1] + for gtest_target in list_of_gtest_targets]) + + return target in GTEST_TARGET_NAMES + + +def _ValidateCommandsAreRelativeToSrcRoot(commands): + for command in commands: + binary_path = _GetBinaryPath(command) + assert binary_path.startswith(BUILD_DIR), ('Target executable "%s" is ' + 'outside of the given build ' + 'directory: "%s". Please make ' + 'sure the command: "%s" is ' + 'relative to the root of the ' + 'checkout.' + %(binary_path, BUILD_DIR, + command)) + + +def _ValidateBuildingWithClangCoverage(): + """Asserts that targets are built with Clang coverage enabled.""" + build_args = _ParseArgsGnFile() + + if (CLANG_COVERAGE_BUILD_ARG not in build_args or + build_args[CLANG_COVERAGE_BUILD_ARG] != 'true'): + assert False, ('\'{} = true\' is required in args.gn.').format( + CLANG_COVERAGE_BUILD_ARG) + + +def _ParseArgsGnFile(): + """Parses args.gn file and returns results as a dictionary. + + Returns: + A dictionary representing the build args. + """ + build_args_path = os.path.join(BUILD_DIR, 'args.gn') + assert os.path.exists(build_args_path), ('"%s" is not a build directory, ' + 'missing args.gn file.' % BUILD_DIR) + with open(build_args_path) as build_args_file: + build_args_lines = build_args_file.readlines() + + build_args = {} + for build_arg_line in build_args_lines: + build_arg_without_comments = build_arg_line.split('#')[0] + key_value_pair = build_arg_without_comments.split('=') + if len(key_value_pair) != 2: + continue + + key = key_value_pair[0].strip() + value = key_value_pair[1].strip() + build_args[key] = value + + return build_args + + +def _ParseCommandArguments(): + """Adds and parses relevant arguments for tool comands. + + Returns: + A dictionary representing the arguments. + """ + arg_parser = argparse.ArgumentParser() + arg_parser.usage = __doc__ + + arg_parser.add_argument('-b', '--build-dir', type=str, required=True, + help='The build directory, the path needs to be ' + 'relative to the root of the checkout.') + + arg_parser.add_argument('-o', '--output-dir', type=str, required=True, + help='Output directory for generated artifacts.') + + arg_parser.add_argument('-c', '--command', action='append', + required=True, + help='Commands used to run test targets, one test ' + 'target needs one and only one command, when ' + 'specifying commands, one should assume the ' + 'current working directory is the root of the ' + 'checkout.') + + arg_parser.add_argument('-j', '--jobs', type=int, default=None, + help='Run N jobs to build in parallel. If not ' + 'specified, a default value will be derived ' + 'based on CPUs availability. Please refer to ' + '\'ninja -h\' for more details.') + + arg_parser.add_argument('targets', nargs='+', + help='The names of the test targets to run.') + + args = arg_parser.parse_args() + return args + + +def Main(): + """Execute tool commands.""" + assert os.path.abspath(os.getcwd()) == SRC_ROOT_PATH, ('This script must be ' + 'called from the root ' + 'of checkout') + DownloadCoverageToolsIfNeeded() + + args = _ParseCommandArguments() + global BUILD_DIR + BUILD_DIR = args.build_dir + global OUTPUT_DIR + OUTPUT_DIR = args.output_dir + + assert len(args.targets) == len(args.command), ('Number of targets must be ' + 'equal to the number of test ' + 'commands.') + assert os.path.exists(BUILD_DIR), ('Build directory: {} doesn\'t exist. ' + 'Please run "gn gen" to generate.').format( + BUILD_DIR) + _ValidateBuildingWithClangCoverage() + _ValidateCommandsAreRelativeToSrcRoot(args.command) + if not os.path.exists(OUTPUT_DIR): + os.makedirs(OUTPUT_DIR) + + profdata_file_path = _CreateCoverageProfileDataForTargets(args.targets, + args.command, + args.jobs) + + binary_paths = [_GetBinaryPath(command) for command in args.command] + _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path) + html_index_file_path = 'file://' + os.path.abspath( + os.path.join(OUTPUT_DIR, 'index.html')) + print('\nCode coverage profile data is created as: %s' % profdata_file_path) + print('index file for html report is generated as: %s' % html_index_file_path) + +if __name__ == '__main__': + sys.exit(Main())
diff --git a/tools/code_coverage/croc.css b/tools/code_coverage/croc.css deleted file mode 100644 index 071822d..0000000 --- a/tools/code_coverage/croc.css +++ /dev/null
@@ -1,102 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -/* - * croc.css - styles for croc HTML output - */ - -body { - font-family:arial; -} - -table { - border-collapse:collapse; - border-width:0px; - border-style:solid; -} - -thead { - background-color:#C0C0E0; - text-align:center; -} - -td { - padding-right:10px; - padding-left:10px; - font-size:small; - border-width:1px; - border-style:solid; - border-color:black; -} - -td.secdesc { - text-align:center; - font-size:medium; - font-weight:bold; - border-width:0px; - border-style:none; - padding-top:10px; - padding-bottom:5px; -} - -td.section { - background-color:#D0D0F0; - text-align:center; -} - -td.stat { - text-align:center; -} - -td.number { - text-align:right; -} - -td.graph { - /* Hide the dummy character */ - color:#FFFFFF; - padding-left:6px; -} - -td.high_pct { - text-align:right; - background-color:#B0FFB0; -} -td.mid_pct { - text-align:right; - background-color:#FFFF90; -} -td.low_pct { - text-align:right; - background-color:#FFB0B0; -} - - -span.missing { - background-color:#FFB0B0; -} -span.instr { - background-color:#FFFF90; -} -span.covered { - background-color:#B0FFB0; -} - -span.g_missing { - background-color:#FF4040; -} -span.g_instr { - background-color:#FFFF00; -} -span.g_covered { - background-color:#40FF40; -} - -p.time { - padding-top:10px; - font-size:small; - font-style:italic; -}
diff --git a/tools/code_coverage/croc.py b/tools/code_coverage/croc.py deleted file mode 100755 index 1b9908a5..0000000 --- a/tools/code_coverage/croc.py +++ /dev/null
@@ -1,722 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 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. - -"""Crocodile - compute coverage numbers for Chrome coverage dashboard.""" - -import optparse -import os -import platform -import re -import sys -import croc_html -import croc_scan - - -class CrocError(Exception): - """Coverage error.""" - - -class CrocStatError(CrocError): - """Error evaluating coverage stat.""" - -#------------------------------------------------------------------------------ - - -class CoverageStats(dict): - """Coverage statistics.""" - - # Default dictionary values for this stat. - DEFAULTS = { 'files_covered': 0, - 'files_instrumented': 0, - 'files_executable': 0, - 'lines_covered': 0, - 'lines_instrumented': 0, - 'lines_executable': 0 } - - def Add(self, coverage_stats): - """Adds a contribution from another coverage stats dict. - - Args: - coverage_stats: Statistics to add to this one. - """ - for k, v in coverage_stats.iteritems(): - if k in self: - self[k] += v - else: - self[k] = v - - def AddDefaults(self): - """Add some default stats which might be assumed present. - - Do not clobber if already present. Adds resilience when evaling a - croc file which expects certain stats to exist.""" - for k, v in self.DEFAULTS.iteritems(): - if not k in self: - self[k] = v - -#------------------------------------------------------------------------------ - - -class CoveredFile(object): - """Information about a single covered file.""" - - def __init__(self, filename, **kwargs): - """Constructor. - - Args: - filename: Full path to file, '/'-delimited. - kwargs: Keyword args are attributes for file. - """ - self.filename = filename - self.attrs = dict(kwargs) - - # Move these to attrs? - self.local_path = None # Local path to file - self.in_lcov = False # Is file instrumented? - - # No coverage data for file yet - self.lines = {} # line_no -> None=executable, 0=instrumented, 1=covered - self.stats = CoverageStats() - - def UpdateCoverage(self): - """Updates the coverage summary based on covered lines.""" - exe = instr = cov = 0 - for l in self.lines.itervalues(): - exe += 1 - if l is not None: - instr += 1 - if l == 1: - cov += 1 - - # Add stats that always exist - self.stats = CoverageStats(lines_executable=exe, - lines_instrumented=instr, - lines_covered=cov, - files_executable=1) - - # Add conditional stats - if cov: - self.stats['files_covered'] = 1 - if instr or self.in_lcov: - self.stats['files_instrumented'] = 1 - -#------------------------------------------------------------------------------ - - -class CoveredDir(object): - """Information about a directory containing covered files.""" - - def __init__(self, dirpath): - """Constructor. - - Args: - dirpath: Full path of directory, '/'-delimited. - """ - self.dirpath = dirpath - - # List of covered files directly in this dir, indexed by filename (not - # full path) - self.files = {} - - # List of subdirs, indexed by filename (not full path) - self.subdirs = {} - - # Dict of CoverageStats objects summarizing all children, indexed by group - self.stats_by_group = {'all': CoverageStats()} - # TODO: by language - - def GetTree(self, indent=''): - """Recursively gets stats for the directory and its children. - - Args: - indent: indent prefix string. - - Returns: - The tree as a string. - """ - dest = [] - - # Compile all groupstats - groupstats = [] - for group in sorted(self.stats_by_group): - s = self.stats_by_group[group] - if not s.get('lines_executable'): - continue # Skip groups with no executable lines - groupstats.append('%s:%d/%d/%d' % ( - group, s.get('lines_covered', 0), - s.get('lines_instrumented', 0), - s.get('lines_executable', 0))) - - outline = '%s%-30s %s' % (indent, - os.path.split(self.dirpath)[1] + '/', - ' '.join(groupstats)) - dest.append(outline.rstrip()) - - for d in sorted(self.subdirs): - dest.append(self.subdirs[d].GetTree(indent=indent + ' ')) - - return '\n'.join(dest) - -#------------------------------------------------------------------------------ - - -class Coverage(object): - """Code coverage for a group of files.""" - - def __init__(self): - """Constructor.""" - self.files = {} # Map filename --> CoverageFile - self.root_dirs = [] # (root, altname) - self.rules = [] # (regexp, dict of RHS attrs) - self.tree = CoveredDir('') - self.print_stats = [] # Dicts of args to PrintStat() - - # Functions which need to be replaced for unit testing - self.add_files_walk = os.walk # Walk function for AddFiles() - self.scan_file = croc_scan.ScanFile # Source scanner for AddFiles() - - def CleanupFilename(self, filename): - """Cleans up a filename. - - Args: - filename: Input filename. - - Returns: - The cleaned up filename. - - Changes all path separators to '/'. - Makes relative paths (those starting with '../' or './' absolute. - Replaces all instances of root dirs with alternate names. - """ - # Change path separators - filename = filename.replace('\\', '/') - - # Windows doesn't care about case sensitivity. - if platform.system() in ['Windows', 'Microsoft']: - filename = filename.lower() - - # If path is relative, make it absolute - # TODO: Perhaps we should default to relative instead, and only understand - # absolute to be files starting with '\', '/', or '[A-Za-z]:'? - if filename.split('/')[0] in ('.', '..'): - filename = os.path.abspath(filename).replace('\\', '/') - - # Replace alternate roots - for root, alt_name in self.root_dirs: - # Windows doesn't care about case sensitivity. - if platform.system() in ['Windows', 'Microsoft']: - root = root.lower() - filename = re.sub('^' + re.escape(root) + '(?=(/|$))', - alt_name, filename) - return filename - - def ClassifyFile(self, filename): - """Applies rules to a filename, to see if we care about it. - - Args: - filename: Input filename. - - Returns: - A dict of attributes for the file, accumulated from the right hand sides - of rules which fired. - """ - attrs = {} - - # Process all rules - for regexp, rhs_dict in self.rules: - if regexp.match(filename): - attrs.update(rhs_dict) - - return attrs - # TODO: Files can belong to multiple groups? - # (test/source) - # (mac/pc/win) - # (media_test/all_tests) - # (small/med/large) - # How to handle that? - - def AddRoot(self, root_path, alt_name='_'): - """Adds a root directory. - - Args: - root_path: Root directory to add. - alt_name: If specified, name of root dir. Otherwise, defaults to '_'. - - Raises: - ValueError: alt_name was blank. - """ - # Alt name must not be blank. If it were, there wouldn't be a way to - # reverse-resolve from a root-replaced path back to the local path, since - # '' would always match the beginning of the candidate filename, resulting - # in an infinite loop. - if not alt_name: - raise ValueError('AddRoot alt_name must not be blank.') - - # Clean up root path based on existing rules - self.root_dirs.append([self.CleanupFilename(root_path), alt_name]) - - def AddRule(self, path_regexp, **kwargs): - """Adds a rule. - - Args: - path_regexp: Regular expression to match for filenames. These are - matched after root directory replacement. - kwargs: Keyword arguments are attributes to set if the rule applies. - - Keyword arguments currently supported: - include: If True, includes matches; if False, excludes matches. Ignored - if None. - group: If not None, sets group to apply to matches. - language: If not None, sets file language to apply to matches. - """ - - # Compile regexp ahead of time - self.rules.append([re.compile(path_regexp), dict(kwargs)]) - - def GetCoveredFile(self, filename, add=False): - """Gets the CoveredFile object for the filename. - - Args: - filename: Name of file to find. - add: If True, will add the file if it's not present. This applies the - transformations from AddRoot() and AddRule(), and only adds the file - if a rule includes it, and it has a group and language. - - Returns: - The matching CoveredFile object, or None if not present. - """ - # Clean filename - filename = self.CleanupFilename(filename) - - # Check for existing match - if filename in self.files: - return self.files[filename] - - # File isn't one we know about. If we can't add it, give up. - if not add: - return None - - # Check rules to see if file can be added. Files must be included and - # have a group and language. - attrs = self.ClassifyFile(filename) - if not (attrs.get('include') - and attrs.get('group') - and attrs.get('language')): - return None - - # Add the file - f = CoveredFile(filename, **attrs) - self.files[filename] = f - - # Return the newly covered file - return f - - def RemoveCoveredFile(self, cov_file): - """Removes the file from the covered file list. - - Args: - cov_file: A file object returned by GetCoveredFile(). - """ - self.files.pop(cov_file.filename) - - def ParseLcovData(self, lcov_data): - """Adds coverage from LCOV-formatted data. - - Args: - lcov_data: An iterable returning lines of data in LCOV format. For - example, a file or list of strings. - """ - cov_file = None - cov_lines = None - for line in lcov_data: - line = line.strip() - if line.startswith('SF:'): - # Start of data for a new file; payload is filename - cov_file = self.GetCoveredFile(line[3:], add=True) - if cov_file: - cov_lines = cov_file.lines - cov_file.in_lcov = True # File was instrumented - elif not cov_file: - # Inside data for a file we don't care about - so skip it - pass - elif line.startswith('DA:'): - # Data point - that is, an executable line in current file - line_no, is_covered = map(int, line[3:].split(',')) - if is_covered: - # Line is covered - cov_lines[line_no] = 1 - elif cov_lines.get(line_no) != 1: - # Line is not covered, so track it as uncovered - cov_lines[line_no] = 0 - elif line == 'end_of_record': - cov_file.UpdateCoverage() - cov_file = None - # (else ignore other line types) - - def ParseLcovFile(self, input_filename): - """Adds coverage data from a .lcov file. - - Args: - input_filename: Input filename. - """ - # TODO: All manner of error checking - lcov_file = None - try: - lcov_file = open(input_filename, 'rt') - self.ParseLcovData(lcov_file) - finally: - if lcov_file: - lcov_file.close() - - def GetStat(self, stat, group='all', default=None): - """Gets a statistic from the coverage object. - - Args: - stat: Statistic to get. May also be an evaluatable python expression, - using the stats. For example, 'stat1 - stat2'. - group: File group to match; if 'all', matches all groups. - default: Value to return if there was an error evaluating the stat. For - example, if the stat does not exist. If None, raises - CrocStatError. - - Returns: - The evaluated stat, or None if error. - - Raises: - CrocStatError: Error evaluating stat. - """ - # TODO: specify a subdir to get the stat from, then walk the tree to - # print the stats from just that subdir - - # Make sure the group exists - if group not in self.tree.stats_by_group: - if default is None: - raise CrocStatError('Group %r not found.' % group) - else: - return default - - stats = self.tree.stats_by_group[group] - # Unit tests use real dicts, not CoverageStats objects, - # so we can't AddDefaults() on them. - if group == 'all' and hasattr(stats, 'AddDefaults'): - stats.AddDefaults() - try: - return eval(stat, {'__builtins__': {'S': self.GetStat}}, stats) - except Exception, e: - if default is None: - raise CrocStatError('Error evaluating stat %r: %s' % (stat, e)) - else: - return default - - def PrintStat(self, stat, format=None, outfile=sys.stdout, **kwargs): - """Prints a statistic from the coverage object. - - Args: - stat: Statistic to get. May also be an evaluatable python expression, - using the stats. For example, 'stat1 - stat2'. - format: Format string to use when printing stat. If None, prints the - stat and its evaluation. - outfile: File stream to output stat to; defaults to stdout. - kwargs: Additional args to pass to GetStat(). - """ - s = self.GetStat(stat, **kwargs) - if format is None: - outfile.write('GetStat(%r) = %s\n' % (stat, s)) - else: - outfile.write(format % s + '\n') - - def AddFiles(self, src_dir): - """Adds files to coverage information. - - LCOV files only contains files which are compiled and instrumented as part - of running coverage. This function finds missing files and adds them. - - Args: - src_dir: Directory on disk at which to start search. May be a relative - path on disk starting with '.' or '..', or an absolute path, or a - path relative to an alt_name for one of the roots - (for example, '_/src'). If the alt_name matches more than one root, - all matches will be attempted. - - Note that dirs not underneath one of the root dirs and covered by an - inclusion rule will be ignored. - """ - # Check for root dir alt_names in the path and replace with the actual - # root dirs, then recurse. - found_root = False - for root, alt_name in self.root_dirs: - replaced_root = re.sub('^' + re.escape(alt_name) + '(?=(/|$))', root, - src_dir) - if replaced_root != src_dir: - found_root = True - self.AddFiles(replaced_root) - if found_root: - return # Replaced an alt_name with a root_dir, so already recursed. - - for (dirpath, dirnames, filenames) in self.add_files_walk(src_dir): - # Make a copy of the dirnames list so we can modify the original to - # prune subdirs we don't need to walk. - for d in list(dirnames): - # Add trailing '/' to directory names so dir-based regexps can match - # '/' instead of needing to specify '(/|$)'. - dpath = self.CleanupFilename(dirpath + '/' + d) + '/' - attrs = self.ClassifyFile(dpath) - if not attrs.get('include'): - # Directory has been excluded, so don't traverse it - # TODO: Document the slight weirdness caused by this: If you - # AddFiles('./A'), and the rules include 'A/B/C/D' but not 'A/B', - # then it won't recurse into './A/B' so won't find './A/B/C/D'. - # Workarounds are to AddFiles('./A/B/C/D') or AddFiles('./A/B/C'). - # The latter works because it explicitly walks the contents of the - # path passed to AddFiles(), so it finds './A/B/C/D'. - dirnames.remove(d) - - for f in filenames: - local_path = dirpath + '/' + f - - covf = self.GetCoveredFile(local_path, add=True) - if not covf: - continue - - # Save where we found the file, for generating line-by-line HTML output - covf.local_path = local_path - - if covf.in_lcov: - # File already instrumented and doesn't need to be scanned - continue - - if not covf.attrs.get('add_if_missing', 1): - # Not allowed to add the file - self.RemoveCoveredFile(covf) - continue - - # Scan file to find potentially-executable lines - lines = self.scan_file(covf.local_path, covf.attrs.get('language')) - if lines: - for l in lines: - covf.lines[l] = None - covf.UpdateCoverage() - else: - # File has no executable lines, so don't count it - self.RemoveCoveredFile(covf) - - def AddConfig(self, config_data, lcov_queue=None, addfiles_queue=None): - """Adds JSON-ish config data. - - Args: - config_data: Config data string. - lcov_queue: If not None, object to append lcov_files to instead of - parsing them immediately. - addfiles_queue: If not None, object to append add_files to instead of - processing them immediately. - """ - # TODO: All manner of error checking - cfg = eval(config_data, {'__builtins__': {}}, {}) - - for rootdict in cfg.get('roots', []): - self.AddRoot(rootdict['root'], alt_name=rootdict.get('altname', '_')) - - for ruledict in cfg.get('rules', []): - regexp = ruledict.pop('regexp') - self.AddRule(regexp, **ruledict) - - for add_lcov in cfg.get('lcov_files', []): - if lcov_queue is not None: - lcov_queue.append(add_lcov) - else: - self.ParseLcovFile(add_lcov) - - for add_path in cfg.get('add_files', []): - if addfiles_queue is not None: - addfiles_queue.append(add_path) - else: - self.AddFiles(add_path) - - self.print_stats += cfg.get('print_stats', []) - - def ParseConfig(self, filename, **kwargs): - """Parses a configuration file. - - Args: - filename: Config filename. - kwargs: Additional parameters to pass to AddConfig(). - """ - # TODO: All manner of error checking - f = None - try: - f = open(filename, 'rt') - # Need to strip CR's from CRLF-terminated lines or posix systems can't - # eval the data. - config_data = f.read().replace('\r\n', '\n') - # TODO: some sort of include syntax. - # - # Needs to be done at string-time rather than at eval()-time, so that - # it's possible to include parts of dicts. Path from a file to its - # include should be relative to the dir containing the file. - # - # Or perhaps it could be done after eval. In that case, there'd be an - # 'include' section with a list of files to include. Those would be - # eval()'d and recursively pre- or post-merged with the including file. - # - # Or maybe just don't worry about it, since multiple configs can be - # specified on the command line. - self.AddConfig(config_data, **kwargs) - finally: - if f: - f.close() - - def UpdateTreeStats(self): - """Recalculates the tree stats from the currently covered files. - - Also calculates coverage summary for files. - """ - self.tree = CoveredDir('') - for cov_file in self.files.itervalues(): - # Add the file to the tree - fdirs = cov_file.filename.split('/') - parent = self.tree - ancestors = [parent] - for d in fdirs[:-1]: - if d not in parent.subdirs: - if parent.dirpath: - parent.subdirs[d] = CoveredDir(parent.dirpath + '/' + d) - else: - parent.subdirs[d] = CoveredDir(d) - parent = parent.subdirs[d] - ancestors.append(parent) - # Final subdir actually contains the file - parent.files[fdirs[-1]] = cov_file - - # Now add file's contribution to coverage by dir - for a in ancestors: - # Add to 'all' group - a.stats_by_group['all'].Add(cov_file.stats) - - # Add to group file belongs to - group = cov_file.attrs.get('group') - if group not in a.stats_by_group: - a.stats_by_group[group] = CoverageStats() - cbyg = a.stats_by_group[group] - cbyg.Add(cov_file.stats) - - def PrintTree(self): - """Prints the tree stats.""" - # Print the tree - print 'Lines of code coverage by directory:' - print self.tree.GetTree() - -#------------------------------------------------------------------------------ - - -def Main(argv): - """Main routine. - - Args: - argv: list of arguments - - Returns: - exit code, 0 for normal exit. - """ - # Parse args - parser = optparse.OptionParser() - parser.add_option( - '-i', '--input', dest='inputs', type='string', action='append', - metavar='FILE', - help='read LCOV input from FILE') - parser.add_option( - '-r', '--root', dest='roots', type='string', action='append', - metavar='ROOT[=ALTNAME]', - help='add ROOT directory, optionally map in coverage results as ALTNAME') - parser.add_option( - '-c', '--config', dest='configs', type='string', action='append', - metavar='FILE', - help='read settings from configuration FILE') - parser.add_option( - '-a', '--addfiles', dest='addfiles', type='string', action='append', - metavar='PATH', - help='add files from PATH to coverage data') - parser.add_option( - '-t', '--tree', dest='tree', action='store_true', - help='print tree of code coverage by group') - parser.add_option( - '-u', '--uninstrumented', dest='uninstrumented', action='store_true', - help='list uninstrumented files') - parser.add_option( - '-m', '--html', dest='html_out', type='string', metavar='PATH', - help='write HTML output to PATH') - parser.add_option( - '-b', '--base_url', dest='base_url', type='string', metavar='URL', - help='include URL in base tag of HTML output') - - parser.set_defaults( - inputs=[], - roots=[], - configs=[], - addfiles=[], - tree=False, - html_out=None, - ) - - options = parser.parse_args(args=argv)[0] - - cov = Coverage() - - # Set root directories for coverage - for root_opt in options.roots: - if '=' in root_opt: - cov.AddRoot(*root_opt.split('=')) - else: - cov.AddRoot(root_opt) - - # Read config files - for config_file in options.configs: - cov.ParseConfig(config_file, lcov_queue=options.inputs, - addfiles_queue=options.addfiles) - - # Parse lcov files - for input_filename in options.inputs: - cov.ParseLcovFile(input_filename) - - # Add missing files - for add_path in options.addfiles: - cov.AddFiles(add_path) - - # Print help if no files specified - if not cov.files: - print 'No covered files found.' - parser.print_help() - return 1 - - # Update tree stats - cov.UpdateTreeStats() - - # Print uninstrumented filenames - if options.uninstrumented: - print 'Uninstrumented files:' - for f in sorted(cov.files): - covf = cov.files[f] - if not covf.in_lcov: - print ' %-6s %-6s %s' % (covf.attrs.get('group'), - covf.attrs.get('language'), f) - - # Print tree stats - if options.tree: - cov.PrintTree() - - # Print stats - for ps_args in cov.print_stats: - cov.PrintStat(**ps_args) - - # Generate HTML - if options.html_out: - html = croc_html.CrocHtml(cov, options.html_out, options.base_url) - html.Write() - - # Normal exit - return 0 - - -if __name__ == '__main__': - sys.exit(Main(sys.argv))
diff --git a/tools/code_coverage/croc_html.py b/tools/code_coverage/croc_html.py deleted file mode 100644 index 7866f472..0000000 --- a/tools/code_coverage/croc_html.py +++ /dev/null
@@ -1,451 +0,0 @@ -# Copyright (c) 2012 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. - -"""Crocodile HTML output.""" - -import os -import shutil -import time -import xml.dom - - -class CrocHtmlError(Exception): - """Coverage HTML error.""" - - -class HtmlElement(object): - """Node in a HTML file.""" - - def __init__(self, doc, element): - """Constructor. - - Args: - doc: XML document object. - element: XML element. - """ - self.doc = doc - self.element = element - - def E(self, name, **kwargs): - """Adds a child element. - - Args: - name: Name of element. - kwargs: Attributes for element. To use an attribute which is a python - reserved word (i.e. 'class'), prefix the attribute name with 'e_'. - - Returns: - The child element. - """ - he = HtmlElement(self.doc, self.doc.createElement(name)) - element = he.element - self.element.appendChild(element) - - for k, v in kwargs.iteritems(): - if k.startswith('e_'): - # Remove prefix - element.setAttribute(k[2:], str(v)) - else: - element.setAttribute(k, str(v)) - - return he - - def Text(self, text): - """Adds a text node. - - Args: - text: Text to add. - - Returns: - self. - """ - t = self.doc.createTextNode(str(text)) - self.element.appendChild(t) - return self - - -class HtmlFile(object): - """HTML file.""" - - def __init__(self, xml_impl, filename): - """Constructor. - - Args: - xml_impl: DOMImplementation to use to create document. - filename: Path to file. - """ - self.xml_impl = xml_impl - doctype = xml_impl.createDocumentType( - 'HTML', '-//W3C//DTD HTML 4.01//EN', - 'http://www.w3.org/TR/html4/strict.dtd') - self.doc = xml_impl.createDocument(None, 'html', doctype) - self.filename = filename - - # Create head and body elements - root = HtmlElement(self.doc, self.doc.documentElement) - self.head = root.E('head') - self.body = root.E('body') - - def Write(self, cleanup=True): - """Writes the file. - - Args: - cleanup: If True, calls unlink() on the internal xml document. This - frees up memory, but means that you can't use this file for anything - else. - """ - f = open(self.filename, 'wt') - self.doc.writexml(f, encoding='UTF-8') - f.close() - - if cleanup: - self.doc.unlink() - # Prevent future uses of the doc now that we've unlinked it - self.doc = None - -#------------------------------------------------------------------------------ - -COV_TYPE_STRING = {None: 'm', 0: 'i', 1: 'E', 2: ' '} -COV_TYPE_CLASS = {None: 'missing', 0: 'instr', 1: 'covered', 2: ''} - - -class CrocHtml(object): - """Crocodile HTML output class.""" - - def __init__(self, cov, output_root, base_url=None): - """Constructor.""" - self.cov = cov - self.output_root = output_root - self.base_url = base_url - self.xml_impl = xml.dom.getDOMImplementation() - self.time_string = 'Coverage information generated %s.' % time.asctime() - - def CreateHtmlDoc(self, filename, title): - """Creates a new HTML document. - - Args: - filename: Filename to write to, relative to self.output_root. - title: Title of page - - Returns: - The document. - """ - f = HtmlFile(self.xml_impl, self.output_root + '/' + filename) - - f.head.E('title').Text(title) - - if self.base_url: - css_href = self.base_url + 'croc.css' - base_href = self.base_url + os.path.dirname(filename) - if not base_href.endswith('/'): - base_href += '/' - f.head.E('base', href=base_href) - else: - css_href = '../' * (len(filename.split('/')) - 1) + 'croc.css' - - f.head.E('link', rel='stylesheet', type='text/css', href=css_href) - - return f - - def AddCaptionForFile(self, body, path): - """Adds a caption for the file, with links to each parent dir. - - Args: - body: Body elemement. - path: Path to file. - """ - # This is slightly different that for subdir, because it needs to have a - # link to the current directory's index.html. - hdr = body.E('h2') - hdr.Text('Coverage for ') - dirs = [''] + path.split('/') - num_dirs = len(dirs) - for i in range(num_dirs - 1): - hdr.E('a', href=( - '../' * (num_dirs - i - 2) + 'index.html')).Text(dirs[i] + '/') - hdr.Text(dirs[-1]) - - def AddCaptionForSubdir(self, body, path): - """Adds a caption for the subdir, with links to each parent dir. - - Args: - body: Body elemement. - path: Path to subdir. - """ - # Link to parent dirs - hdr = body.E('h2') - hdr.Text('Coverage for ') - dirs = [''] + path.split('/') - num_dirs = len(dirs) - for i in range(num_dirs - 1): - hdr.E('a', href=( - '../' * (num_dirs - i - 1) + 'index.html')).Text(dirs[i] + '/') - hdr.Text(dirs[-1] + '/') - - def AddSectionHeader(self, table, caption, itemtype, is_file=False): - """Adds a section header to the coverage table. - - Args: - table: Table to add rows to. - caption: Caption for section, if not None. - itemtype: Type of items in this section, if not None. - is_file: Are items in this section files? - """ - - if caption is not None: - table.E('tr').E('th', e_class='secdesc', colspan=8).Text(caption) - - sec_hdr = table.E('tr') - - if itemtype is not None: - sec_hdr.E('th', e_class='section').Text(itemtype) - - sec_hdr.E('th', e_class='section').Text('Coverage') - sec_hdr.E('th', e_class='section', colspan=3).Text( - 'Lines executed / instrumented / missing') - - graph = sec_hdr.E('th', e_class='section') - graph.E('span', style='color:#00FF00').Text('exe') - graph.Text(' / ') - graph.E('span', style='color:#FFFF00').Text('inst') - graph.Text(' / ') - graph.E('span', style='color:#FF0000').Text('miss') - - if is_file: - sec_hdr.E('th', e_class='section').Text('Language') - sec_hdr.E('th', e_class='section').Text('Group') - else: - sec_hdr.E('th', e_class='section', colspan=2) - - def AddItem(self, table, itemname, stats, attrs, link=None): - """Adds a bar graph to the element. This is a series of <td> elements. - - Args: - table: Table to add item to. - itemname: Name of item. - stats: Stats object. - attrs: Attributes dictionary; if None, no attributes will be printed. - link: Destination for itemname hyperlink, if not None. - """ - row = table.E('tr') - - # Add item name - if itemname is not None: - item_elem = row.E('td') - if link is not None: - item_elem = item_elem.E('a', href=link) - item_elem.Text(itemname) - - # Get stats - stat_exe = stats.get('lines_executable', 0) - stat_ins = stats.get('lines_instrumented', 0) - stat_cov = stats.get('lines_covered', 0) - - percent = row.E('td') - - # Add text - row.E('td', e_class='number').Text(stat_cov) - row.E('td', e_class='number').Text(stat_ins) - row.E('td', e_class='number').Text(stat_exe - stat_ins) - - # Add percent and graph; only fill in if there's something in there - graph = row.E('td', e_class='graph', width=100) - if stat_exe: - percent_cov = 100.0 * stat_cov / stat_exe - percent_ins = 100.0 * stat_ins / stat_exe - - # Color percent based on thresholds - percent.Text('%.1f%%' % percent_cov) - if percent_cov >= 80: - percent.element.setAttribute('class', 'high_pct') - elif percent_cov >= 60: - percent.element.setAttribute('class', 'mid_pct') - else: - percent.element.setAttribute('class', 'low_pct') - - # Graphs use integer values - percent_cov = int(percent_cov) - percent_ins = int(percent_ins) - - graph.Text('.') - graph.E('span', style='padding-left:%dpx' % percent_cov, - e_class='g_covered') - graph.E('span', style='padding-left:%dpx' % (percent_ins - percent_cov), - e_class='g_instr') - graph.E('span', style='padding-left:%dpx' % (100 - percent_ins), - e_class='g_missing') - - if attrs: - row.E('td', e_class='stat').Text(attrs.get('language')) - row.E('td', e_class='stat').Text(attrs.get('group')) - else: - row.E('td', colspan=2) - - def WriteFile(self, cov_file): - """Writes the HTML for a file. - - Args: - cov_file: croc.CoveredFile to write. - """ - print ' ' + cov_file.filename - title = 'Coverage for ' + cov_file.filename - - f = self.CreateHtmlDoc(cov_file.filename + '.html', title) - body = f.body - - # Write header section - self.AddCaptionForFile(body, cov_file.filename) - - # Summary for this file - table = body.E('table') - self.AddSectionHeader(table, None, None, is_file=True) - self.AddItem(table, None, cov_file.stats, cov_file.attrs) - - body.E('h2').Text('Line-by-line coverage:') - - # Print line-by-line coverage - if cov_file.local_path: - code_table = body.E('table').E('tr').E('td').E('pre') - - flines = open(cov_file.local_path, 'rt') - lineno = 0 - - for line in flines: - lineno += 1 - line_cov = cov_file.lines.get(lineno, 2) - e_class = COV_TYPE_CLASS.get(line_cov) - - code_table.E('span', e_class=e_class).Text('%4d %s : %s\n' % ( - lineno, - COV_TYPE_STRING.get(line_cov), - line.rstrip() - )) - - else: - body.Text('Line-by-line coverage not available. Make sure the directory' - ' containing this file has been scanned via ') - body.E('B').Text('add_files') - body.Text(' in a configuration file, or the ') - body.E('B').Text('--addfiles') - body.Text(' command line option.') - - # TODO: if file doesn't have a local path, try to find it by - # reverse-mapping roots and searching for the file. - - body.E('p', e_class='time').Text(self.time_string) - f.Write() - - def WriteSubdir(self, cov_dir): - """Writes the index.html for a subdirectory. - - Args: - cov_dir: croc.CoveredDir to write. - """ - print ' ' + cov_dir.dirpath + '/' - - # Create the subdir if it doesn't already exist - subdir = self.output_root + '/' + cov_dir.dirpath - if not os.path.exists(subdir): - os.mkdir(subdir) - - if cov_dir.dirpath: - title = 'Coverage for ' + cov_dir.dirpath + '/' - f = self.CreateHtmlDoc(cov_dir.dirpath + '/index.html', title) - else: - title = 'Coverage summary' - f = self.CreateHtmlDoc('index.html', title) - - body = f.body - - dirs = [''] + cov_dir.dirpath.split('/') - num_dirs = len(dirs) - sort_jsfile = '../' * (num_dirs - 1) + 'sorttable.js' - script = body.E('script', src=sort_jsfile) - body.E('/script') - - # Write header section - if cov_dir.dirpath: - self.AddCaptionForSubdir(body, cov_dir.dirpath) - else: - body.E('h2').Text(title) - - table = body.E('table', e_class='sortable') - table.E('h3').Text('Coverage by Group') - # Coverage by group - self.AddSectionHeader(table, None, 'Group') - - for group in sorted(cov_dir.stats_by_group): - self.AddItem(table, group, cov_dir.stats_by_group[group], None) - - # List subdirs - if cov_dir.subdirs: - table = body.E('table', e_class='sortable') - table.E('h3').Text('Subdirectories') - self.AddSectionHeader(table, None, 'Subdirectory') - - for d in sorted(cov_dir.subdirs): - self.AddItem(table, d + '/', cov_dir.subdirs[d].stats_by_group['all'], - None, link=d + '/index.html') - - # List files - if cov_dir.files: - table = body.E('table', e_class='sortable') - table.E('h3').Text('Files in This Directory') - self.AddSectionHeader(table, None, 'Filename', - is_file=True) - - for filename in sorted(cov_dir.files): - cov_file = cov_dir.files[filename] - self.AddItem(table, filename, cov_file.stats, cov_file.attrs, - link=filename + '.html') - - body.E('p', e_class='time').Text(self.time_string) - f.Write() - - def WriteRoot(self): - """Writes the files in the output root.""" - # Find ourselves - src_dir = os.path.split(self.WriteRoot.func_code.co_filename)[0] - - # Files to copy into output root - copy_files = ['croc.css'] - # Third_party files to copy into output root - third_party_files = ['sorttable.js'] - - # Copy files from our directory into the output directory - for copy_file in copy_files: - print ' Copying %s' % copy_file - shutil.copyfile(os.path.join(src_dir, copy_file), - os.path.join(self.output_root, copy_file)) - # Copy third party files from third_party directory into - # the output directory - src_dir = os.path.join(src_dir, 'third_party') - for third_party_file in third_party_files: - print ' Copying %s' % third_party_file - shutil.copyfile(os.path.join(src_dir, third_party_file), - os.path.join(self.output_root, third_party_file)) - - def Write(self): - """Writes HTML output.""" - - print 'Writing HTML to %s...' % self.output_root - - # Loop through the tree and write subdirs, breadth-first - # TODO: switch to depth-first and sort values - makes nicer output? - todo = [self.cov.tree] - while todo: - cov_dir = todo.pop(0) - - # Append subdirs to todo list - todo += cov_dir.subdirs.values() - - # Write this subdir - self.WriteSubdir(cov_dir) - - # Write files in this subdir - for cov_file in cov_dir.files.itervalues(): - self.WriteFile(cov_file) - - # Write files in root directory - self.WriteRoot()
diff --git a/tools/code_coverage/croc_scan.py b/tools/code_coverage/croc_scan.py deleted file mode 100644 index 8d0e2e8d..0000000 --- a/tools/code_coverage/croc_scan.py +++ /dev/null
@@ -1,164 +0,0 @@ -# Copyright (c) 2011 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. - -"""Crocodile source scanners.""" - - -import re - - -class Scanner(object): - """Generic source scanner.""" - - def __init__(self): - """Constructor.""" - - self.re_token = re.compile('#') - self.comment_to_eol = ['#'] - self.comment_start = None - self.comment_end = None - - def ScanLines(self, lines): - """Scans the lines for executable statements. - - Args: - lines: Iterator returning source lines. - - Returns: - An array of line numbers which are executable. - """ - exe_lines = [] - lineno = 0 - - in_string = None - in_comment = None - comment_index = None - - for line in lines: - lineno += 1 - in_string_at_start = in_string - - for t in self.re_token.finditer(line): - tokenstr = t.groups()[0] - - if in_comment: - # Inside a multi-line comment, so look for end token - if tokenstr == in_comment: - in_comment = None - # Replace comment with spaces - line = (line[:comment_index] - + ' ' * (t.end(0) - comment_index) - + line[t.end(0):]) - - elif in_string: - # Inside a string, so look for end token - if tokenstr == in_string: - in_string = None - - elif tokenstr in self.comment_to_eol: - # Single-line comment, so truncate line at start of token - line = line[:t.start(0)] - break - - elif tokenstr == self.comment_start: - # Multi-line comment start - end token is comment_end - in_comment = self.comment_end - comment_index = t.start(0) - - else: - # Starting a string - end token is same as start - in_string = tokenstr - - # If still in comment at end of line, remove comment - if in_comment: - line = line[:comment_index] - # Next line, delete from the beginnine - comment_index = 0 - - # If line-sans-comments is not empty, claim it may be executable - if line.strip() or in_string_at_start: - exe_lines.append(lineno) - - # Return executable lines - return exe_lines - - def Scan(self, filename): - """Reads the file and scans its lines. - - Args: - filename: Path to file to scan. - - Returns: - An array of line numbers which are executable. - """ - - # TODO: All manner of error checking - f = None - try: - f = open(filename, 'rt') - return self.ScanLines(f) - finally: - if f: - f.close() - - -class PythonScanner(Scanner): - """Python source scanner.""" - - def __init__(self): - """Constructor.""" - Scanner.__init__(self) - - # TODO: This breaks for strings ending in more than 2 backslashes. Need - # a pattern which counts only an odd number of backslashes, so the last - # one thus escapes the quote. - self.re_token = re.compile(r'(#|\'\'\'|"""|(?<!(?<!\\)\\)["\'])') - self.comment_to_eol = ['#'] - self.comment_start = None - self.comment_end = None - - -class CppScanner(Scanner): - """C / C++ / ObjC / ObjC++ source scanner.""" - - def __init__(self): - """Constructor.""" - Scanner.__init__(self) - - # TODO: This breaks for strings ending in more than 2 backslashes. Need - # a pattern which counts only an odd number of backslashes, so the last - # one thus escapes the quote. - self.re_token = re.compile(r'(^\s*#|//|/\*|\*/|(?<!(?<!\\)\\)["\'])') - - # TODO: Treat '\' at EOL as a token, and handle it as continuing the - # previous line. That is, if in a comment-to-eol, this line is a comment - # too. - - # Note that we treat # at beginning of line as a comment, so that we ignore - # preprocessor definitions - self.comment_to_eol = ['//', '#'] - - self.comment_start = '/*' - self.comment_end = '*/' - - -def ScanFile(filename, language): - """Scans a file for executable lines. - - Args: - filename: Path to file to scan. - language: Language for file ('C', 'C++', 'python', 'ObjC', 'ObjC++') - - Returns: - A list of executable lines, or an empty list if the file was not a handled - language. - """ - - if language == 'python': - return PythonScanner().Scan(filename) - elif language in ['C', 'C++', 'ObjC', 'ObjC++']: - return CppScanner().Scan(filename) - - # Something we don't handle - return []
diff --git a/tools/code_coverage/croc_scan_test.py b/tools/code_coverage/croc_scan_test.py deleted file mode 100755 index a69b28a..0000000 --- a/tools/code_coverage/croc_scan_test.py +++ /dev/null
@@ -1,187 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 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. - -"""Unit tests for croc_scan.py.""" - -import re -import unittest -import croc_scan - - -class TestScanner(unittest.TestCase): - """Tests for croc_scan.Scanner.""" - - def testInit(self): - """Test __init()__.""" - s = croc_scan.Scanner() - - self.assertEqual(s.re_token.pattern, '#') - self.assertEqual(s.comment_to_eol, ['#']) - self.assertEqual(s.comment_start, None) - self.assertEqual(s.comment_end, None) - - def testScanLines(self): - """Test ScanLines().""" - s = croc_scan.Scanner() - # Set up imaginary language: - # ':' = comment to EOL - # '"' = string start/end - # '(' = comment start - # ')' = comment end - s.re_token = re.compile(r'([\:\"\(\)])') - s.comment_to_eol = [':'] - s.comment_start = '(' - s.comment_end = ')' - - # No input file = no output lines - self.assertEqual(s.ScanLines([]), []) - - # Empty lines and lines with only whitespace are ignored - self.assertEqual(s.ScanLines([ - '', # 1 - 'line', # 2 exe - ' \t ', # 3 - ]), [2]) - - # Comments to EOL are stripped, but not inside strings - self.assertEqual(s.ScanLines([ - 'test', # 1 exe - ' : A comment', # 2 - '"a : in a string"', # 3 exe - 'test2 : with comment to EOL', # 4 exe - 'foo = "a multiline string with an empty line', # 5 exe - '', # 6 exe - ': and a comment-to-EOL character"', # 7 exe - ': done', # 8 - ]), [1, 3, 4, 5, 6, 7]) - - # Test Comment start/stop detection - self.assertEqual(s.ScanLines([ - '( a comment on one line)', # 1 - 'text (with a comment)', # 2 exe - '( a comment with a : in the middle)', # 3 - '( a multi-line', # 4 - ' comment)', # 5 - 'a string "with a ( in it"', # 6 exe - 'not in a multi-line comment', # 7 exe - '(a comment with a " in it)', # 8 - ': not in a string, so this gets stripped', # 9 - 'more text "with an uninteresting string"', # 10 exe - ]), [2, 6, 7, 10]) - - # TODO: Test Scan(). Low priority, since it just wraps ScanLines(). - - -class TestPythonScanner(unittest.TestCase): - """Tests for croc_scan.PythonScanner.""" - - def testScanLines(self): - """Test ScanLines().""" - s = croc_scan.PythonScanner() - - # No input file = no output lines - self.assertEqual(s.ScanLines([]), []) - - self.assertEqual(s.ScanLines([ - '# a comment', # 1 - '', # 2 - '"""multi-line string', # 3 exe - '# not a comment', # 4 exe - 'end of multi-line string"""', # 5 exe - ' ', # 6 - '"single string with #comment"', # 7 exe - '', # 8 - '\'\'\'multi-line string, single-quote', # 9 exe - '# not a comment', # 10 exe - 'end of multi-line string\'\'\'', # 11 exe - '', # 12 - '"string with embedded \\" is handled"', # 13 exe - '# quoted "', # 14 - '"\\""', # 15 exe - '# quoted backslash', # 16 - '"\\\\"', # 17 exe - 'main()', # 18 exe - '# end', # 19 - ]), [3, 4, 5, 7, 9, 10, 11, 13, 15, 17, 18]) - - -class TestCppScanner(unittest.TestCase): - """Tests for croc_scan.CppScanner.""" - - def testScanLines(self): - """Test ScanLines().""" - s = croc_scan.CppScanner() - - # No input file = no output lines - self.assertEqual(s.ScanLines([]), []) - - self.assertEqual(s.ScanLines([ - '// a comment', # 1 - '# a preprocessor define', # 2 - '', # 3 - '\'#\', \'"\'', # 4 exe - '', # 5 - '/* a multi-line comment', # 6 - 'with a " in it', # 7 - '*/', # 8 - '', # 9 - '"a string with /* and \' in it"', # 10 exe - '', # 11 - '"a multi-line string\\', # 12 exe - '// not a comment\\', # 13 exe - 'ending here"', # 14 exe - '', # 15 - '"string with embedded \\" is handled"', # 16 exe - '', # 17 - 'main()', # 18 exe - '// end', # 19 - ]), [4, 10, 12, 13, 14, 16, 18]) - - -class TestScanFile(unittest.TestCase): - """Tests for croc_scan.ScanFile().""" - - class MockScanner(object): - """Mock scanner.""" - - def __init__(self, language): - """Constructor.""" - self.language = language - - def Scan(self, filename): - """Mock Scan() method.""" - return 'scan %s %s' % (self.language, filename) - - def MockPythonScanner(self): - return self.MockScanner('py') - - def MockCppScanner(self): - return self.MockScanner('cpp') - - def setUp(self): - """Per-test setup.""" - # Hook scanners - self.old_python_scanner = croc_scan.PythonScanner - self.old_cpp_scanner = croc_scan.CppScanner - croc_scan.PythonScanner = self.MockPythonScanner - croc_scan.CppScanner = self.MockCppScanner - - def tearDown(self): - """Per-test cleanup.""" - croc_scan.PythonScanner = self.old_python_scanner - croc_scan.CppScanner = self.old_cpp_scanner - - def testScanFile(self): - """Test ScanFile().""" - self.assertEqual(croc_scan.ScanFile('foo', 'python'), 'scan py foo') - self.assertEqual(croc_scan.ScanFile('bar1', 'C'), 'scan cpp bar1') - self.assertEqual(croc_scan.ScanFile('bar2', 'C++'), 'scan cpp bar2') - self.assertEqual(croc_scan.ScanFile('bar3', 'ObjC'), 'scan cpp bar3') - self.assertEqual(croc_scan.ScanFile('bar4', 'ObjC++'), 'scan cpp bar4') - self.assertEqual(croc_scan.ScanFile('bar', 'fortran'), []) - - -if __name__ == '__main__': - unittest.main()
diff --git a/tools/code_coverage/croc_test.py b/tools/code_coverage/croc_test.py deleted file mode 100755 index 7c2521c..0000000 --- a/tools/code_coverage/croc_test.py +++ /dev/null
@@ -1,758 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 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. - -"""Unit tests for Crocodile.""" - -import os -import StringIO -import unittest -import croc - - -class TestCoverageStats(unittest.TestCase): - """Tests for croc.CoverageStats.""" - - def testAdd(self): - """Test Add().""" - c = croc.CoverageStats() - - # Initially empty - self.assertEqual(c, {}) - - # Add items - c['a'] = 1 - c['b'] = 0 - self.assertEqual(c, {'a': 1, 'b': 0}) - - # Add dict with non-overlapping items - c.Add({'c': 5}) - self.assertEqual(c, {'a': 1, 'b': 0, 'c': 5}) - - # Add dict with overlapping items - c.Add({'a': 4, 'd': 3}) - self.assertEqual(c, {'a': 5, 'b': 0, 'c': 5, 'd': 3}) - - -class TestCoveredFile(unittest.TestCase): - """Tests for croc.CoveredFile.""" - - def setUp(self): - self.cov_file = croc.CoveredFile('bob.cc', group='source', language='C++') - - def testInit(self): - """Test init.""" - f = self.cov_file - - # Check initial values - self.assertEqual(f.filename, 'bob.cc') - self.assertEqual(f.attrs, {'group': 'source', 'language': 'C++'}) - self.assertEqual(f.lines, {}) - self.assertEqual(f.stats, {}) - self.assertEqual(f.local_path, None) - self.assertEqual(f.in_lcov, False) - - def testUpdateCoverageEmpty(self): - """Test updating coverage when empty.""" - f = self.cov_file - f.UpdateCoverage() - self.assertEqual(f.stats, { - 'lines_executable': 0, - 'lines_instrumented': 0, - 'lines_covered': 0, - 'files_executable': 1, - }) - - def testUpdateCoverageExeOnly(self): - """Test updating coverage when no lines are instrumented.""" - f = self.cov_file - f.lines = {1: None, 2: None, 4: None} - f.UpdateCoverage() - self.assertEqual(f.stats, { - 'lines_executable': 3, - 'lines_instrumented': 0, - 'lines_covered': 0, - 'files_executable': 1, - }) - - # Now mark the file instrumented via in_lcov - f.in_lcov = True - f.UpdateCoverage() - self.assertEqual(f.stats, { - 'lines_executable': 3, - 'lines_instrumented': 0, - 'lines_covered': 0, - 'files_executable': 1, - 'files_instrumented': 1, - }) - - def testUpdateCoverageExeAndInstr(self): - """Test updating coverage when no lines are covered.""" - f = self.cov_file - f.lines = {1: None, 2: None, 4: 0, 5: 0, 7: None} - f.UpdateCoverage() - self.assertEqual(f.stats, { - 'lines_executable': 5, - 'lines_instrumented': 2, - 'lines_covered': 0, - 'files_executable': 1, - 'files_instrumented': 1, - }) - - def testUpdateCoverageWhenCovered(self): - """Test updating coverage when lines are covered.""" - f = self.cov_file - f.lines = {1: None, 2: None, 3: 1, 4: 0, 5: 0, 6: 1, 7: None} - f.UpdateCoverage() - self.assertEqual(f.stats, { - 'lines_executable': 7, - 'lines_instrumented': 4, - 'lines_covered': 2, - 'files_executable': 1, - 'files_instrumented': 1, - 'files_covered': 1, - }) - - -class TestCoveredDir(unittest.TestCase): - """Tests for croc.CoveredDir.""" - - def setUp(self): - self.cov_dir = croc.CoveredDir('/a/b/c') - - def testInit(self): - """Test init.""" - d = self.cov_dir - - # Check initial values - self.assertEqual(d.dirpath, '/a/b/c') - self.assertEqual(d.files, {}) - self.assertEqual(d.subdirs, {}) - self.assertEqual(d.stats_by_group, {'all': {}}) - - def testGetTreeEmpty(self): - """Test getting empty tree.""" - d = self.cov_dir - self.assertEqual(d.GetTree(), 'c/') - - def testGetTreeStats(self): - """Test getting tree with stats.""" - d = self.cov_dir - d.stats_by_group['all'] = croc.CoverageStats( - lines_executable=50, lines_instrumented=30, lines_covered=20) - d.stats_by_group['bar'] = croc.CoverageStats( - lines_executable=0, lines_instrumented=0, lines_covered=0) - d.stats_by_group['foo'] = croc.CoverageStats( - lines_executable=33, lines_instrumented=22, lines_covered=11) - # 'bar' group is skipped because it has no executable lines - self.assertEqual( - d.GetTree(), - 'c/ all:20/30/50 foo:11/22/33') - - def testGetTreeSubdir(self): - """Test getting tree with subdirs.""" - d1 = self.cov_dir = croc.CoveredDir('/a') - d2 = self.cov_dir = croc.CoveredDir('/a/b') - d3 = self.cov_dir = croc.CoveredDir('/a/c') - d4 = self.cov_dir = croc.CoveredDir('/a/b/d') - d5 = self.cov_dir = croc.CoveredDir('/a/b/e') - d1.subdirs = {'/a/b': d2, '/a/c': d3} - d2.subdirs = {'/a/b/d': d4, '/a/b/e': d5} - self.assertEqual(d1.GetTree(), 'a/\n b/\n d/\n e/\n c/') - - -class TestCoverage(unittest.TestCase): - """Tests for croc.Coverage.""" - - def MockWalk(self, src_dir): - """Mock for os.walk(). - - Args: - src_dir: Source directory to walk. - - Returns: - A list of (dirpath, dirnames, filenames) tuples. - """ - self.mock_walk_calls.append(src_dir) - return self.mock_walk_return - - def MockScanFile(self, filename, language): - """Mock for croc_scan.ScanFile(). - - Args: - filename: Path to file to scan. - language: Language for file. - - Returns: - A list of executable lines. - """ - self.mock_scan_calls.append([filename, language]) - if filename in self.mock_scan_return: - return self.mock_scan_return[filename] - else: - return self.mock_scan_return['default'] - - def setUp(self): - """Per-test setup.""" - - # Empty coverage object - self.cov = croc.Coverage() - - # Coverage object with minimal setup - self.cov_minimal = croc.Coverage() - self.cov_minimal.AddRoot('/src') - self.cov_minimal.AddRoot('c:\\source') - self.cov_minimal.AddRule('^_/', include=1, group='my') - self.cov_minimal.AddRule('.*\\.c$', language='C') - self.cov_minimal.AddRule('.*\\.c##$', language='C##') # sharper than thou - - # Data for MockWalk() - self.mock_walk_calls = [] - self.mock_walk_return = [] - - # Data for MockScanFile() - self.mock_scan_calls = [] - self.mock_scan_return = {'default': [1]} - - def testInit(self): - """Test init.""" - c = self.cov - self.assertEqual(c.files, {}) - self.assertEqual(c.root_dirs, []) - self.assertEqual(c.print_stats, []) - self.assertEqual(c.rules, []) - - def testAddRoot(self): - """Test AddRoot() and CleanupFilename().""" - c = self.cov - - # Check for identity on already-clean filenames - self.assertEqual(c.CleanupFilename(''), '') - self.assertEqual(c.CleanupFilename('a'), 'a') - self.assertEqual(c.CleanupFilename('.a'), '.a') - self.assertEqual(c.CleanupFilename('..a'), '..a') - self.assertEqual(c.CleanupFilename('a.b'), 'a.b') - self.assertEqual(c.CleanupFilename('a/b/c'), 'a/b/c') - self.assertEqual(c.CleanupFilename('a/b/c/'), 'a/b/c/') - - # Backslash to forward slash - self.assertEqual(c.CleanupFilename('a\\b\\c'), 'a/b/c') - - # Handle relative paths - self.assertEqual(c.CleanupFilename('.'), - c.CleanupFilename(os.path.abspath('.'))) - self.assertEqual(c.CleanupFilename('..'), - c.CleanupFilename(os.path.abspath('..'))) - self.assertEqual(c.CleanupFilename('./foo/bar'), - c.CleanupFilename(os.path.abspath('./foo/bar'))) - self.assertEqual(c.CleanupFilename('../../a/b/c'), - c.CleanupFilename(os.path.abspath('../../a/b/c'))) - - # Replace alt roots - c.AddRoot('foo') - self.assertEqual(c.CleanupFilename('foo'), '_') - self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_/bar/baz') - self.assertEqual(c.CleanupFilename('aaa/foo'), 'aaa/foo') - - # Alt root replacement is applied for all roots - c.AddRoot('foo/bar', '_B') - self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_B/baz') - - # Can use previously defined roots in cleanup - c.AddRoot('_/nom/nom/nom', '_CANHAS') - self.assertEqual(c.CleanupFilename('foo/nom/nom/nom/cheezburger'), - '_CANHAS/cheezburger') - - # Verify roots starting with UNC paths or drive letters work, and that - # more than one root can point to the same alt_name - c.AddRoot('/usr/local/foo', '_FOO') - c.AddRoot('D:\\my\\foo', '_FOO') - self.assertEqual(c.CleanupFilename('/usr/local/foo/a/b'), '_FOO/a/b') - self.assertEqual(c.CleanupFilename('D:\\my\\foo\\c\\d'), '_FOO/c/d') - - # Cannot specify a blank alt_name - self.assertRaises(ValueError, c.AddRoot, 'some_dir', '') - - def testAddRule(self): - """Test AddRule() and ClassifyFile().""" - c = self.cov - - # With only the default rule, nothing gets kept - self.assertEqual(c.ClassifyFile('_/src/'), {}) - self.assertEqual(c.ClassifyFile('_/src/a.c'), {}) - - # Add rules to include a tree and set a default group - c.AddRule('^_/src/', include=1, group='source') - self.assertEqual(c.ClassifyFile('_/src/'), - {'include': 1, 'group': 'source'}) - self.assertEqual(c.ClassifyFile('_/notsrc/'), {}) - self.assertEqual(c.ClassifyFile('_/src/a.c'), - {'include': 1, 'group': 'source'}) - - # Define some languages and groups - c.AddRule('.*\\.(c|h)$', language='C') - c.AddRule('.*\\.py$', language='Python') - c.AddRule('.*_test\\.', group='test') - self.assertEqual(c.ClassifyFile('_/src/a.c'), - {'include': 1, 'group': 'source', 'language': 'C'}) - self.assertEqual(c.ClassifyFile('_/src/a.h'), - {'include': 1, 'group': 'source', 'language': 'C'}) - self.assertEqual(c.ClassifyFile('_/src/a.cpp'), - {'include': 1, 'group': 'source'}) - self.assertEqual(c.ClassifyFile('_/src/a_test.c'), - {'include': 1, 'group': 'test', 'language': 'C'}) - self.assertEqual(c.ClassifyFile('_/src/test_a.c'), - {'include': 1, 'group': 'source', 'language': 'C'}) - self.assertEqual(c.ClassifyFile('_/src/foo/bar.py'), - {'include': 1, 'group': 'source', 'language': 'Python'}) - self.assertEqual(c.ClassifyFile('_/src/test.py'), - {'include': 1, 'group': 'source', 'language': 'Python'}) - - # Exclude a path (for example, anything in a build output dir) - c.AddRule('.*/build/', include=0) - # But add back in a dir which matched the above rule but isn't a build - # output dir - c.AddRule('_/src/tools/build/', include=1) - self.assertEqual(c.ClassifyFile('_/src/build.c').get('include'), 1) - self.assertEqual(c.ClassifyFile('_/src/build/').get('include'), 0) - self.assertEqual(c.ClassifyFile('_/src/build/a.c').get('include'), 0) - self.assertEqual(c.ClassifyFile('_/src/tools/build/').get('include'), 1) - self.assertEqual(c.ClassifyFile('_/src/tools/build/t.c').get('include'), 1) - - def testGetCoveredFile(self): - """Test GetCoveredFile().""" - c = self.cov_minimal - - # Not currently any covered files - self.assertEqual(c.GetCoveredFile('_/a.c'), None) - - # Add some files - a_c = c.GetCoveredFile('_/a.c', add=True) - b_c = c.GetCoveredFile('_/b.c##', add=True) - self.assertEqual(a_c.filename, '_/a.c') - self.assertEqual(a_c.attrs, {'include': 1, 'group': 'my', 'language': 'C'}) - self.assertEqual(b_c.filename, '_/b.c##') - self.assertEqual(b_c.attrs, - {'include': 1, 'group': 'my', 'language': 'C##'}) - - # Specifying the same filename should return the existing object - self.assertEqual(c.GetCoveredFile('_/a.c'), a_c) - self.assertEqual(c.GetCoveredFile('_/a.c', add=True), a_c) - - # Filenames get cleaned on the way in, as do root paths - self.assertEqual(c.GetCoveredFile('/src/a.c'), a_c) - self.assertEqual(c.GetCoveredFile('c:\\source\\a.c'), a_c) - - # TODO: Make sure that covered files require language, group, and include - # (since that checking is now done in GetCoveredFile() rather than - # ClassifyFile()) - - def testRemoveCoveredFile(self): - """Test RemoveCoveredFile().""" - # TODO: TEST ME! - - def testParseLcov(self): - """Test ParseLcovData().""" - c = self.cov_minimal - - c.ParseLcovData([ - '# Ignore unknown lines', - # File we should include' - 'SF:/src/a.c', - 'DA:10,1', - 'DA:11,0', - 'DA:12,1 \n', # Trailing whitespace should get stripped - 'end_of_record', - # File we should ignore - 'SF:/not_src/a.c', - 'DA:20,1', - 'end_of_record', - # Same as first source file, but alternate root - 'SF:c:\\source\\a.c', - 'DA:30,1', - 'end_of_record', - # Ignore extra end of record - 'end_of_record', - # Ignore data points after end of record - 'DA:40,1', - # Instrumented but uncovered file - 'SF:/src/b.c', - 'DA:50,0', - 'end_of_record', - # Empty file (instrumented but no executable lines) - 'SF:c:\\source\\c.c', - 'end_of_record', - ]) - - # We should know about three files - self.assertEqual(sorted(c.files), ['_/a.c', '_/b.c', '_/c.c']) - - # Check expected contents - a_c = c.GetCoveredFile('_/a.c') - self.assertEqual(a_c.lines, {10: 1, 11: 0, 12: 1, 30: 1}) - self.assertEqual(a_c.stats, { - 'files_executable': 1, - 'files_instrumented': 1, - 'files_covered': 1, - 'lines_instrumented': 4, - 'lines_executable': 4, - 'lines_covered': 3, - }) - self.assertEqual(a_c.in_lcov, True) - - b_c = c.GetCoveredFile('_/b.c') - self.assertEqual(b_c.lines, {50: 0}) - self.assertEqual(b_c.stats, { - 'files_executable': 1, - 'files_instrumented': 1, - 'lines_instrumented': 1, - 'lines_executable': 1, - 'lines_covered': 0, - }) - self.assertEqual(b_c.in_lcov, True) - - c_c = c.GetCoveredFile('_/c.c') - self.assertEqual(c_c.lines, {}) - self.assertEqual(c_c.stats, { - 'files_executable': 1, - 'files_instrumented': 1, - 'lines_instrumented': 0, - 'lines_executable': 0, - 'lines_covered': 0, - }) - self.assertEqual(c_c.in_lcov, True) - - # TODO: Test that files are marked as instrumented if they come from lcov, - # even if they don't have any instrumented lines. (and that in_lcov is set - # for those files - probably should set that via some method rather than - # directly...) - - def testGetStat(self): - """Test GetStat() and PrintStat().""" - c = self.cov - - # Add some stats, so there's something to report - c.tree.stats_by_group = { - 'all': { - 'count_a': 10, - 'count_b': 4, - 'foo': 'bar', - }, - 'tests': { - 'count_a': 2, - 'count_b': 5, - 'baz': 'bob', - }, - } - - # Test missing stats and groups - self.assertRaises(croc.CrocStatError, c.GetStat, 'nosuch') - self.assertRaises(croc.CrocStatError, c.GetStat, 'baz') - self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='tests') - self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='nosuch') - - # Test returning defaults - self.assertEqual(c.GetStat('nosuch', default=13), 13) - self.assertEqual(c.GetStat('baz', default='aaa'), 'aaa') - self.assertEqual(c.GetStat('foo', group='tests', default=0), 0) - self.assertEqual(c.GetStat('foo', group='nosuch', default=''), '') - - # Test getting stats - self.assertEqual(c.GetStat('count_a'), 10) - self.assertEqual(c.GetStat('count_a', group='tests'), 2) - self.assertEqual(c.GetStat('foo', default='baz'), 'bar') - - # Test stat math (eval) - self.assertEqual(c.GetStat('count_a - count_b'), 6) - self.assertEqual(c.GetStat('100.0 * count_a / count_b', group='tests'), - 40.0) - # Should catch eval errors - self.assertRaises(croc.CrocStatError, c.GetStat, '100 / 0') - self.assertRaises(croc.CrocStatError, c.GetStat, 'count_a -') - - # Test nested stats via S() - self.assertEqual(c.GetStat('count_a - S("count_a", group="tests")'), 8) - self.assertRaises(croc.CrocStatError, c.GetStat, 'S()') - self.assertRaises(croc.CrocStatError, c.GetStat, 'S("nosuch")') - - # Test PrintStat() - # We won't see the first print, but at least verify it doesn't assert - c.PrintStat('count_a', format='(test to stdout: %s)') - # Send subsequent prints to a file - f = StringIO.StringIO() - c.PrintStat('count_b', outfile=f) - # Test specifying output format - c.PrintStat('count_a', format='Count A = %05d', outfile=f) - # Test specifing additional keyword args - c.PrintStat('count_a', group='tests', outfile=f) - c.PrintStat('nosuch', default=42, outfile=f) - self.assertEqual(f.getvalue(), ("""\ -GetStat('count_b') = 4 -Count A = 00010 -GetStat('count_a') = 2 -GetStat('nosuch') = 42 -""")) - f.close() - - def testAddConfigEmpty(self): - """Test AddConfig() with empty config.""" - c = self.cov - # Most minimal config is an empty dict; should do nothing - c.AddConfig('{} # And we ignore comments') - - def testAddConfig(self): - """Test AddConfig().""" - c = self.cov - lcov_queue = [] - addfiles_queue = [] - - c.AddConfig("""{ - 'roots' : [ - {'root' : '/foo'}, - {'root' : '/bar', 'altname' : 'BAR'}, - ], - 'rules' : [ - {'regexp' : '^_/', 'group' : 'apple'}, - {'regexp' : 're2', 'include' : 1, 'language' : 'elvish'}, - ], - 'lcov_files' : ['a.lcov', 'b.lcov'], - 'add_files' : ['/src', 'BAR/doo'], - 'print_stats' : [ - {'stat' : 'count_a'}, - {'stat' : 'count_b', 'group' : 'tests'}, - ], - 'extra_key' : 'is ignored', - }""", lcov_queue=lcov_queue, addfiles_queue=addfiles_queue) - - self.assertEqual(lcov_queue, ['a.lcov', 'b.lcov']) - self.assertEqual(addfiles_queue, ['/src', 'BAR/doo']) - self.assertEqual(c.root_dirs, [['/foo', '_'], ['/bar', 'BAR']]) - self.assertEqual(c.print_stats, [ - {'stat': 'count_a'}, - {'stat': 'count_b', 'group': 'tests'}, - ]) - # Convert compiled re's back to patterns for comparison - rules = [[r[0].pattern] + r[1:] for r in c.rules] - self.assertEqual(rules, [ - ['^_/', {'group': 'apple'}], - ['re2', {'include': 1, 'language': 'elvish'}], - ]) - - def testAddFilesSimple(self): - """Test AddFiles() simple call.""" - c = self.cov_minimal - c.add_files_walk = self.MockWalk - c.scan_file = self.MockScanFile - - c.AddFiles('/a/b/c') - self.assertEqual(self.mock_walk_calls, ['/a/b/c']) - self.assertEqual(self.mock_scan_calls, []) - self.assertEqual(c.files, {}) - - def testAddFilesRootMap(self): - """Test AddFiles() with root mappings.""" - c = self.cov_minimal - c.add_files_walk = self.MockWalk - c.scan_file = self.MockScanFile - - c.AddRoot('_/subdir', 'SUBDIR') - - # AddFiles() should replace the 'SUBDIR' alt_name, then match both - # possible roots for the '_' alt_name. - c.AddFiles('SUBDIR/foo') - self.assertEqual(self.mock_walk_calls, - ['/src/subdir/foo', 'c:/source/subdir/foo']) - self.assertEqual(self.mock_scan_calls, []) - self.assertEqual(c.files, {}) - - def testAddFilesNonEmpty(self): - """Test AddFiles() where files are returned.""" - - c = self.cov_minimal - c.add_files_walk = self.MockWalk - c.scan_file = self.MockScanFile - - # Add a rule to exclude a subdir - c.AddRule('^_/proj1/excluded/', include=0) - - # Add a rule to exclude adding some fiels - c.AddRule('.*noscan.c$', add_if_missing=0) - - # Set data for mock walk and scan - self.mock_walk_return = [ - [ - '/src/proj1', - ['excluded', 'subdir'], - ['a.c', 'no.f', 'yes.c', 'noexe.c', 'bob_noscan.c'], - ], - [ - '/src/proj1/subdir', - [], - ['cherry.c'], - ], - ] - - # Add a file with no executable lines; it should be scanned but not added - self.mock_scan_return['/src/proj1/noexe.c'] = [] - - c.AddFiles('/src/proj1') - - self.assertEqual(self.mock_walk_calls, ['/src/proj1']) - self.assertEqual(self.mock_scan_calls, [ - ['/src/proj1/a.c', 'C'], - ['/src/proj1/yes.c', 'C'], - ['/src/proj1/noexe.c', 'C'], - ['/src/proj1/subdir/cherry.c', 'C'], - ]) - - # Include files from the main dir and subdir - self.assertEqual(sorted(c.files), [ - '_/proj1/a.c', - '_/proj1/subdir/cherry.c', - '_/proj1/yes.c']) - - # Excluded dir should have been pruned from the mock walk data dirnames. - # In the real os.walk() call this prunes the walk. - self.assertEqual(self.mock_walk_return[0][1], ['subdir']) - - - def testEmptyTreeStats(self): - """Make sure we don't choke when absolutely nothing happened. - - How we might hit this: bot compile error.""" - c = self.cov_minimal - t = c.tree - t.stats_by_group['all'].AddDefaults() - self.assertEqual(t.stats_by_group, { - 'all': { 'files_covered': 0, - 'files_instrumented': 0, - 'files_executable': 0, - 'lines_covered': 0, - 'lines_instrumented': 0, - 'lines_executable': 0 }}) - - def testUpdateTreeStats(self): - """Test UpdateTreeStats().""" - - c = self.cov_minimal - c.AddRule('.*_test', group='test') - - # Fill the files list - c.ParseLcovData([ - 'SF:/src/a.c', - 'DA:10,1', 'DA:11,1', 'DA:20,0', - 'end_of_record', - 'SF:/src/a_test.c', - 'DA:10,1', 'DA:11,1', 'DA:12,1', - 'end_of_record', - 'SF:/src/foo/b.c', - 'DA:10,1', 'DA:11,1', 'DA:20,0', 'DA:21,0', 'DA:30,0', - 'end_of_record', - 'SF:/src/foo/b_test.c', - 'DA:20,0', 'DA:21,0', 'DA:22,0', - 'end_of_record', - ]) - c.UpdateTreeStats() - - t = c.tree - self.assertEqual(t.dirpath, '') - self.assertEqual(sorted(t.files), []) - self.assertEqual(sorted(t.subdirs), ['_']) - self.assertEqual(t.stats_by_group, { - 'all': { - 'files_covered': 3, - 'files_executable': 4, - 'lines_executable': 14, - 'lines_covered': 7, - 'lines_instrumented': 14, - 'files_instrumented': 4, - }, - 'my': { - 'files_covered': 2, - 'files_executable': 2, - 'lines_executable': 8, - 'lines_covered': 4, - 'lines_instrumented': 8, - 'files_instrumented': 2, - }, - 'test': { - 'files_covered': 1, - 'files_executable': 2, - 'lines_executable': 6, - 'lines_covered': 3, - 'lines_instrumented': 6, - 'files_instrumented': 2, - }, - }) - - t = t.subdirs['_'] - self.assertEqual(t.dirpath, '_') - self.assertEqual(sorted(t.files), ['a.c', 'a_test.c']) - self.assertEqual(sorted(t.subdirs), ['foo']) - self.assertEqual(t.stats_by_group, { - 'all': { - 'files_covered': 3, - 'files_executable': 4, - 'lines_executable': 14, - 'lines_covered': 7, - 'lines_instrumented': 14, - 'files_instrumented': 4, - }, - 'my': { - 'files_covered': 2, - 'files_executable': 2, - 'lines_executable': 8, - 'lines_covered': 4, - 'lines_instrumented': 8, - 'files_instrumented': 2, - }, - 'test': { - 'files_covered': 1, - 'files_executable': 2, - 'lines_executable': 6, - 'lines_covered': 3, - 'lines_instrumented': 6, - 'files_instrumented': 2, - }, - }) - - t = t.subdirs['foo'] - self.assertEqual(t.dirpath, '_/foo') - self.assertEqual(sorted(t.files), ['b.c', 'b_test.c']) - self.assertEqual(sorted(t.subdirs), []) - self.assertEqual(t.stats_by_group, { - 'test': { - 'files_executable': 1, - 'files_instrumented': 1, - 'lines_executable': 3, - 'lines_instrumented': 3, - 'lines_covered': 0, - }, - 'all': { - 'files_covered': 1, - 'files_executable': 2, - 'lines_executable': 8, - 'lines_covered': 2, - 'lines_instrumented': 8, - 'files_instrumented': 2, - }, - 'my': { - 'files_covered': 1, - 'files_executable': 1, - 'lines_executable': 5, - 'lines_covered': 2, - 'lines_instrumented': 5, - 'files_instrumented': 1, - } - }) - - # TODO: test: less important, since these are thin wrappers around other - # tested methods. - # ParseConfig() - # ParseLcovFile() - # PrintTree() - - -if __name__ == '__main__': - unittest.main()
diff --git a/tools/code_coverage/example.croc b/tools/code_coverage/example.croc deleted file mode 100644 index 4e8ca2b..0000000 --- a/tools/code_coverage/example.croc +++ /dev/null
@@ -1,197 +0,0 @@ -# -*- python -*- - -# Copyright (c) 2012 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. - -# Example configuration file for Croc - -# Basic formatting rules: -# * It looks like JSON. -# * It's really python. -# * Dictionaries are wrapped in {}. Order does not matter. Entries are of -# the form: -# 'key':value, -# Note the trailing comma, which will help save you from python's built-in -# string concatenation. -# * Lists are wrapped in []. Order does matter. Entries should be followed -# with a trailing comma, which will help save you from python's built-in -# string concatenation. -# * Comments start with # and extend to end of line. -# * Strings are wrapped in ''. Backslashes must be escaped ('foo\\bar', not -# 'foo\bar') - this is particularly important in rule regular expressions. - - -# What follows is the main configuration dictionary. -{ - # List of root directories, applied in order. - # - # Typically, coverage data files contain absolute paths to the sources. - # What you care about is usually a relative path from the top of your source - # tree (referred to here as a 'source root') to the sources. - # - # Roots may also be specified on the command line via the --root option. - # Roots specified by --root are applied before those specified in config - # files. - 'roots' : [ - # Each entry is a dict. - # * It must contain a 'root' entry, which is the start of a path. - # * Root entries may be absolute paths - # * Root entries starting with './' or '../' are relative paths, and - # are taken relative to the current directory where you run croc. - # * Root entries may start with previously defined altnames. - # * Use '/' as a path separator, even on Windows. - # * It may contain a 'altname' entry. If the root matches the start of - # a filename, that start is replaced with the 'altname', or with '_' - # if no default is specified. - # * Multiple root entries may share the same altname. This is commonly - # used when combining LCOV files from different platforms into one - # coverage report, when each platform checks out source code into a - # different source tree. - {'root' : 'c:/P4/EarthHammer'}, - {'root' : 'd:/pulse/recipes/330137642/base'}, - {'root' : '/Volumes/BuildData/PulseData/data/recipes/330137640/base'}, - {'root' : '/usr/local/google/builder/.pulse-agent/data/recipes/330137641/base'}, - - # Sub-paths we specifically care about and want to call out. Note that - # these are relative to the default '_' altname. - { - 'root' : '_/googleclient/third_party/software_construction_toolkit/files', - 'altname' : 'SCT', - }, - { - 'root' : '_/googleclient/tools/hammer', - 'altname' : 'HAMMER', - }, - ], - - # List of rules, applied in order. - 'rules' : [ - # Each rule is a dict. - # * It must contaihn a 'regexp' entry. Filenames which match this - # regular expression (after applying mappings from 'roots') are - # affected by the rule. - # - # * Other entries in the dict are attributes to apply to matching files. - # - # Allowed attributes: - # - # 'include' : If 1, the file will be included in coverage reports. If 0, - # it won't be included in coverage reports. - # - # 'group' : Name of the group the file belongs to. The most common - # group names are 'source' and 'test'. Files must belong to - # a group to be included in coverage reports. - # - # 'language' : Programming language for the file. The most common - # languages are 'C', 'C++', 'python', 'ObjC', 'ObjC++'. - # Files must have a language to be included in coverage - # reports. - # - # 'add_if_missing' : If 1, and the file was not referenced by any LCOV - # files, it will be be scanned for executable lines - # and added to the coverage report. If 0, if the - # file is not referenced by any LCOV files, it will - # simply be ignored and not present in coverage - # reports. - - # Files/paths to include - { - 'regexp' : '^(SCT|HAMMER)/', - 'include' : 1, - 'add_if_missing': 1, - }, - { - 'regexp' : '.*/(\\.svn|\\.hg)/', - 'include' : 0, - }, - - # Groups - { - 'regexp' : '', - 'group' : 'source', - }, - { - 'regexp' : '.*_(test|test_mac|unittest)\\.', - 'group' : 'test', - }, - - # Languages - { - 'regexp' : '.*\\.py$', - 'language' : 'python', - }, - ], - - # List of paths to add source from. - # - # Each entry is a path. It may be a local path, or one relative to a root - # altname (see 'roots' above). - # - # If more than one root's altname matches the start of this path, all matches - # will be attempted; matches where the candidate directory doesn't exist will - # be ignored. For example, if you're combining data from multiple platforms' - # LCOV files, you probably defined at least one root per LCOV, but only have - # one copy of the source on your local platform. That's fine; Croc will use - # the source it can find and not worry about the source it can't. - # - # Source files must be added via 'add_files' to generate line-by-line HTML - # output (via the --html option) and/or to scan for missing executable lines - # (if 'add_if_missing' is 1). - 'add_files' : [ - 'SCT', - 'HAMMER', - ], - - # Statistics to print. - # - 'print_stats' : [ - # Each entry is a dict. - # - # It must have a 'stat' entry, which is the statistic to print. This may - # be one of the following stats: - # - # * files_executable - # * files_instrumented - # * files_covered - # * lines_executable - # * lines_instrumented - # * lines_covered - # - # or an expression using those stats. - # - # It may have a 'format' entry, which is a python formatting string (very - # printf-like) for the statistic. - # - # It may have a 'group' entry. If this is specified, only files from the - # matching group will be included in the statistic. If not specified, the - # group defaults to 'all', which means all groups. - { - 'stat' : 'files_executable', - 'format' : '*RESULT FilesKnown: files_executable= %d files', - }, - { - 'stat' : 'files_instrumented', - 'format' : '*RESULT FilesInstrumented: files_instrumented= %d files', - }, - { - 'stat' : '100.0 * files_instrumented / files_executable', - 'format' : '*RESULT FilesInstrumentedPercent: files_instrumented_percent= %g', - }, - { - 'stat' : 'lines_instrumented', - 'format' : '*RESULT LinesInstrumented: lines_instrumented= %d lines', - }, - { - 'stat' : 'lines_covered', - 'format' : '*RESULT LinesCoveredSource: lines_covered_source= %d lines', - 'group' : 'source', - }, - { - 'stat' : 'lines_covered', - 'format' : '*RESULT LinesCoveredTest: lines_covered_test= %d lines', - 'group' : 'test', - }, - ], - -}
diff --git a/tools/code_coverage/third_party/README.chromium b/tools/code_coverage/third_party/README.chromium deleted file mode 100644 index a492552..0000000 --- a/tools/code_coverage/third_party/README.chromium +++ /dev/null
@@ -1,11 +0,0 @@ -Name: SortTable -Short Name: sorttable.js -URL: http://www.kryogenix.org/code/browser/sorttable/ -Version: 2 -Date: 7th April 2007 -License: Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - -Description: -Add <script src="sorttable.js"></script> to your HTML -Add class="sortable" to any table you'd like to make sortable -Click on the headers to sort
diff --git a/tools/code_coverage/third_party/sorttable.js b/tools/code_coverage/third_party/sorttable.js deleted file mode 100644 index 16ef551..0000000 --- a/tools/code_coverage/third_party/sorttable.js +++ /dev/null
@@ -1,494 +0,0 @@ -/* - SortTable - version 2 - 7th April 2007 - Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ - - Instructions: - Download this file - Add <script src="sorttable.js"></script> to your HTML - Add class="sortable" to any table you'd like to make sortable - Click on the headers to sort - - Thanks to many, many people for contributions and suggestions. - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - This basically means: do what you want with it. -*/ - - -var stIsIE = /*@cc_on!@*/false; - -sorttable = { - init: function() { - // quit if this function has already been called - if (arguments.callee.done) return; - // flag this function so we don't do the same thing twice - arguments.callee.done = true; - // kill the timer - if (_timer) clearInterval(_timer); - - if (!document.createElement || !document.getElementsByTagName) return; - - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - - forEach(document.getElementsByTagName('table'), function(table) { - if (table.className.search(/\bsortable\b/) != -1) { - sorttable.makeSortable(table); - } - }); - - }, - - makeSortable: function(table) { - if (table.getElementsByTagName('thead').length == 0) { - // table doesn't have a tHead. Since it should have, create one and - // put the first table row in it. - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the,table.firstChild); - } - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - - if (table.tHead.rows.length != 1) return; // can't cope with two header rows - - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as - // "total" rows, for example). This is B&R, since what you're supposed - // to do is put them in a tfoot. So, if there are sortbottom rows, - // for backwards compatibility, move them to tfoot (creating it if needed). - sortbottomrows = []; - for (var i=0; i<table.rows.length; i++) { - if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { - sortbottomrows[sortbottomrows.length] = table.rows[i]; - } - } - if (sortbottomrows) { - if (table.tFoot == null) { - // table doesn't have a tfoot. Create one. - tfo = document.createElement('tfoot'); - table.appendChild(tfo); - } - for (var i=0; i<sortbottomrows.length; i++) { - tfo.appendChild(sortbottomrows[i]); - } - delete sortbottomrows; - } - - // work through each column and calculate its type - headrow = table.tHead.rows[0].cells; - for (var i=0; i<headrow.length; i++) { - // manually override the type with a sorttable_type attribute - if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col - mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); - if (mtch) { override = mtch[1]; } - if (mtch && typeof sorttable["sort_"+override] == 'function') { - headrow[i].sorttable_sortfunction = sorttable["sort_"+override]; - } else { - headrow[i].sorttable_sortfunction = sorttable.guessType(table,i); - } - // make it clickable to sort - headrow[i].sorttable_columnindex = i; - headrow[i].sorttable_tbody = table.tBodies[0]; - dean_addEvent(headrow[i],"click", function(e) { - - if (this.className.search(/\bsorttable_sorted\b/) != -1) { - // if we're already sorted by this column, just - // reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted', - 'sorttable_sorted_reverse'); - this.removeChild(document.getElementById('sorttable_sortfwdind')); - sortrevind = document.createElement('span'); - sortrevind.id = "sorttable_sortrevind"; - sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴'; - this.appendChild(sortrevind); - return; - } - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just - // re-reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted_reverse', - 'sorttable_sorted'); - this.removeChild(document.getElementById('sorttable_sortrevind')); - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; - this.appendChild(sortfwdind); - return; - } - - // remove sorttable_sorted classes - theadrow = this.parentNode; - forEach(theadrow.childNodes, function(cell) { - if (cell.nodeType == 1) { // an element - cell.className = cell.className.replace('sorttable_sorted_reverse',''); - cell.className = cell.className.replace('sorttable_sorted',''); - } - }); - sortfwdind = document.getElementById('sorttable_sortfwdind'); - if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } - sortrevind = document.getElementById('sorttable_sortrevind'); - if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } - - this.className += ' sorttable_sorted'; - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; - this.appendChild(sortfwdind); - - // build an array to sort. This is a Schwartzian transform thing, - // i.e., we "decorate" each row with the actual sort key, - // sort based on the sort keys, and then put the rows back in order - // which is a lot faster because you only do getInnerText once per row - row_array = []; - col = this.sorttable_columnindex; - rows = this.sorttable_tbody.rows; - for (var j=0; j<rows.length; j++) { - row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; - } - /* If you want a stable sort, uncomment the following line */ - //sorttable.shaker_sort(row_array, this.sorttable_sortfunction); - /* and comment out this one */ - row_array.sort(this.sorttable_sortfunction); - - tb = this.sorttable_tbody; - for (var j=0; j<row_array.length; j++) { - tb.appendChild(row_array[j][1]); - } - - delete row_array; - }); - } - } - }, - - guessType: function(table, column) { - // guess the type of a column based on its first non-blank row - sortfn = sorttable.sort_alpha; - for (var i=0; i<table.tBodies[0].rows.length; i++) { - text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); - if (text != '') { - if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) { - return sorttable.sort_numeric; - } - // check for a date: dd/mm/yyyy or dd/mm/yy - // can have / or . or - as separator - // can be mm/dd as well - possdate = text.match(sorttable.DATE_RE) - if (possdate) { - // looks like a date - first = parseInt(possdate[1]); - second = parseInt(possdate[2]); - if (first > 12) { - // definitely dd/mm - return sorttable.sort_ddmm; - } else if (second > 12) { - return sorttable.sort_mmdd; - } else { - // looks like a date, but we can't tell which, so assume - // that it's dd/mm (English imperialism!) and keep looking - sortfn = sorttable.sort_ddmm; - } - } - } - } - return sortfn; - }, - - getInnerText: function(node) { - // gets the text we want to use for sorting for a cell. - // strips leading and trailing whitespace. - // this is *not* a generic getInnerText function; it's special to sorttable. - // for example, you can override the cell text with a customkey attribute. - // it also gets .value for <input> fields. - - if (!node) return ""; - - hasInputs = (typeof node.getElementsByTagName == 'function') && - node.getElementsByTagName('input').length; - - if (node.getAttribute("sorttable_customkey") != null) { - return node.getAttribute("sorttable_customkey"); - } - else if (typeof node.textContent != 'undefined' && !hasInputs) { - return node.textContent.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.innerText != 'undefined' && !hasInputs) { - return node.innerText.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.text != 'undefined' && !hasInputs) { - return node.text.replace(/^\s+|\s+$/g, ''); - } - else { - switch (node.nodeType) { - case 3: - if (node.nodeName.toLowerCase() == 'input') { - return node.value.replace(/^\s+|\s+$/g, ''); - } - case 4: - return node.nodeValue.replace(/^\s+|\s+$/g, ''); - break; - case 1: - case 11: - var innerText = ''; - for (var i = 0; i < node.childNodes.length; i++) { - innerText += sorttable.getInnerText(node.childNodes[i]); - } - return innerText.replace(/^\s+|\s+$/g, ''); - break; - default: - return ''; - } - } - }, - - reverse: function(tbody) { - // reverse the rows in a tbody - newrows = []; - for (var i=0; i<tbody.rows.length; i++) { - newrows[newrows.length] = tbody.rows[i]; - } - for (var i=newrows.length-1; i>=0; i--) { - tbody.appendChild(newrows[i]); - } - delete newrows; - }, - - /* sort functions - each sort function takes two parameters, a and b - you are comparing a[0] and b[0] */ - sort_numeric: function(a,b) { - aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); - if (isNaN(aa)) aa = 0; - bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); - if (isNaN(bb)) bb = 0; - return aa-bb; - }, - sort_alpha: function(a,b) { - if (a[0]==b[0]) return 0; - if (a[0]<b[0]) return -1; - return 1; - }, - sort_ddmm: function(a,b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; m = mtch[2]; d = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt1 = y+m+d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; m = mtch[2]; d = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt2 = y+m+d; - if (dt1==dt2) return 0; - if (dt1<dt2) return -1; - return 1; - }, - sort_mmdd: function(a,b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; d = mtch[2]; m = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt1 = y+m+d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; d = mtch[2]; m = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt2 = y+m+d; - if (dt1==dt2) return 0; - if (dt1<dt2) return -1; - return 1; - }, - - shaker_sort: function(list, comp_func) { - // A stable sort function to allow multi-level sorting of data - // see: http://en.wikipedia.org/wiki/Cocktail_sort - // thanks to Joseph Nahmias - var b = 0; - var t = list.length - 1; - var swap = true; - - while(swap) { - swap = false; - for(var i = b; i < t; ++i) { - if ( comp_func(list[i], list[i+1]) > 0 ) { - var q = list[i]; list[i] = list[i+1]; list[i+1] = q; - swap = true; - } - } // for - t--; - - if (!swap) break; - - for(var i = t; i > b; --i) { - if ( comp_func(list[i], list[i-1]) < 0 ) { - var q = list[i]; list[i] = list[i-1]; list[i-1] = q; - swap = true; - } - } // for - b++; - - } // while(swap) - } -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - document.addEventListener("DOMContentLoaded", sorttable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); - var script = document.getElementById("__ie_onload"); - script.onreadystatechange = function() { - if (this.readyState == "complete") { - sorttable.init(); // call the onload handler - } - }; -/*@end @*/ - -/* for Safari */ -if (/WebKit/i.test(navigator.userAgent)) { // sniff - var _timer = setInterval(function() { - if (/loaded|complete/.test(document.readyState)) { - sorttable.init(); // call the onload handler - } - }, 10); -} - -/* for other browsers */ -window.onload = sorttable.init; - -// written by Dean Edwards, 2005 -// with input from Tino Zijdel, Matthias Miller, Diego Perini - -// http://dean.edwards.name/weblog/2005/10/add-event/ - -function dean_addEvent(element, type, handler) { - if (element.addEventListener) { - element.addEventListener(type, handler, false); - } else { - // assign each event handler a unique ID - if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++; - // create a hash table of event types for the element - if (!element.events) element.events = {}; - // create a hash table of event handlers for each element/event pair - var handlers = element.events[type]; - if (!handlers) { - handlers = element.events[type] = {}; - // store the existing event handler (if there is one) - if (element["on" + type]) { - handlers[0] = element["on" + type]; - } - } - // store the event handler in the hash table - handlers[handler.$$guid] = handler; - // assign a global event handler to do all the work - element["on" + type] = handleEvent; - } -}; -// a counter used to create unique IDs -dean_addEvent.guid = 1; - -function removeEvent(element, type, handler) { - if (element.removeEventListener) { - element.removeEventListener(type, handler, false); - } else { - // delete the event handler from the hash table - if (element.events && element.events[type]) { - delete element.events[type][handler.$$guid]; - } - } -}; - -function handleEvent(event) { - var returnValue = true; - // grab the event object (IE uses a global event object) - event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); - // get a reference to the hash table of event handlers - var handlers = this.events[event.type]; - // execute each event handler - for (var i in handlers) { - this.$$handleEvent = handlers[i]; - if (this.$$handleEvent(event) === false) { - returnValue = false; - } - } - return returnValue; -}; - -function fixEvent(event) { - // add W3C standard event methods - event.preventDefault = fixEvent.preventDefault; - event.stopPropagation = fixEvent.stopPropagation; - return event; -}; -fixEvent.preventDefault = function() { - this.returnValue = false; -}; -fixEvent.stopPropagation = function() { - this.cancelBubble = true; -} - -// Dean's forEach: http://dean.edwards.name/base/forEach.js -/* - forEach, version 1.0 - Copyright 2006, Dean Edwards - License: http://www.opensource.org/licenses/mit-license.php -*/ - -// array-like enumeration -if (!Array.forEach) { // mozilla already supports this - Array.forEach = function(array, block, context) { - for (var i = 0; i < array.length; i++) { - block.call(context, array[i], i, array); - } - }; -} - -// generic enumeration -Function.prototype.forEach = function(object, block, context) { - for (var key in object) { - if (typeof this.prototype[key] == "undefined") { - block.call(context, object[key], key, object); - } - } -}; - -// character enumeration -String.forEach = function(string, block, context) { - Array.forEach(string.split(""), function(chr, index) { - block.call(context, chr, index, string); - }); -}; - -// globally resolve forEach enumeration -var forEach = function(object, block, context) { - if (object) { - var resolve = Object; // default - if (object instanceof Function) { - // functions have a "length" property - resolve = Function; - } else if (object.forEach instanceof Function) { - // the object implements a custom forEach method so use that - object.forEach(block, context); - return; - } else if (typeof object == "string") { - // the object is a string - resolve = String; - } else if (typeof object.length == "number") { - // the object is array-like - resolve = Array; - } - resolve.forEach(object, block, context); - } -};
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 7cfc7f2..50628be 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -102648,6 +102648,9 @@ </histogram_suffixes> <histogram_suffixes name="LowMemoryMargin" separator="_"> + <obsolete> + Deprecated 12/2017. The low memory margin is a per-platform constant. + </obsolete> <suffix name="default" label="Low memory margin set to the system default"/> <suffix name="off" label="Low memory notification disabled"/> <suffix name="0mb" label="Low memory margin set to 0MB"/>
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc index 8fba648..3060f64 100644 --- a/ui/views/layout/grid_layout.cc +++ b/ui/views/layout/grid_layout.cc
@@ -364,6 +364,10 @@ const bool pref_width_fixed; const bool pref_height_fixed; + // The preferred size, only set during the preferred size pass + // (SizeCalculationType::PREFERRED). + gfx::Size pref_size; + // The width/height. This is one of possible three values: // . an explicitly set value (if pref_X_fixed is true). If an explicitly set // value was provided, then this value never changes. @@ -630,6 +634,7 @@ size.set_height(view_state->height); } else { size = view_state->view->GetPreferredSize(); + view_state->pref_size = size; } if (!view_state->pref_width_fixed) view_state->width = size.width(); @@ -986,20 +991,22 @@ // view and update the rows ascent/descent. // . Reset the remaining_height of each view state. // . If the width the view will be given is different than it's pref, ask - // for the height given a particularly width. + // for the height given the actual width. for (const auto& view_state : view_states_) { view_state->remaining_height = view_state->height; if (view_state->v_align == BASELINE) view_state->baseline = view_state->view->GetBaseline(); - if (view_state->h_align == FILL) { - // The view is resizable. As the pref height may vary with the width, - // ask for the pref again. - int actual_width = - view_state->column_set->GetColumnWidth(view_state->start_col, - view_state->col_span); - if (actual_width != view_state->width && !view_state->pref_height_fixed) { + if (!view_state->pref_height_fixed) { + // If the view is given a different width than it's preferred width + // requery for the preferred height. This is necessary as the preferred + // height may depend upon the width. + int actual_width = view_state->column_set->GetColumnWidth( + view_state->start_col, view_state->col_span); + int x = 0; // Not used in this stage. + CalculateSize(view_state->width, view_state->h_align, &x, &actual_width); + if (actual_width != view_state->width) { // The width this view will get differs from its preferred. Some Views // pref height varies with its width; ask for the preferred again. view_state->height = view_state->view->GetHeightForWidth(actual_width);
diff --git a/ui/views/layout/grid_layout_unittest.cc b/ui/views/layout/grid_layout_unittest.cc index 31bc7c6..f993c6f 100644 --- a/ui/views/layout/grid_layout_unittest.cc +++ b/ui/views/layout/grid_layout_unittest.cc
@@ -1023,4 +1023,35 @@ EXPECT_EQ(gfx::Rect(10, 0, 50, 10), view2->bounds()); } +class SettablePreferredHeightView : public View { + public: + explicit SettablePreferredHeightView(int height) : pref_height_(height) {} + ~SettablePreferredHeightView() override = default; + + // View: + int GetHeightForWidth(int width) const override { return pref_height_; } + + private: + const int pref_height_; + + DISALLOW_COPY_AND_ASSIGN(SettablePreferredHeightView); +}; + +TEST_F(GridLayoutTest, HeightForWidthCalledWhenNotGivenPreferredWidth) { + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, GridLayout::USE_PREF, + 0, 0); + layout()->StartRow(0, 0); + const int pref_height = 100; + // |view| is owned by parent. + SettablePreferredHeightView* view = + new SettablePreferredHeightView(pref_height); + const gfx::Size pref(10, 20); + view->SetPreferredSize(pref); + layout()->AddView(view); + + EXPECT_EQ(pref, GetPreferredSize()); + EXPECT_EQ(pref_height, host().GetHeightForWidth(5)); +} + } // namespace views