From 520490e404aeffdeb3524ad49b679bafe69345b0 Mon Sep 17 00:00:00 2001 From: Liang-Heng Chen Date: Mon, 20 May 2019 08:48:02 +0000 Subject: [PATCH 001/129] Bug 1552536 - add dummy page load origin; r=chutten Differential Revision: https://phabricator.services.mozilla.com/D31666 --HG-- extra : moz-landing-system : lando --- dom/base/ContentBlockingLog.cpp | 16 ++- .../telemetry/core/TelemetryOriginData.inc | 3 + .../telemetry/tests/gtest/TestOrigins.cpp | 117 +++++++++--------- 3 files changed, 73 insertions(+), 63 deletions(-) diff --git a/dom/base/ContentBlockingLog.cpp b/dom/base/ContentBlockingLog.cpp index f68c287ca9a1..1bab0857c55f 100644 --- a/dom/base/ContentBlockingLog.cpp +++ b/dom/base/ContentBlockingLog.cpp @@ -21,6 +21,9 @@ typedef mozilla::Telemetry::OriginMetricID OriginMetricID; namespace mozilla { namespace dom { +// sync with TelemetryOriginData.inc +NS_NAMED_LITERAL_CSTRING(kDummyOriginHash, "PAGELOAD"); + // randomly choose 1% users included in the content blocking measurement // based on their client id. static constexpr double kRatioReportUser = 0.01; @@ -111,6 +114,12 @@ void ContentBlockingLog::ReportLog() { return; } LOG("ContentBlockingLog::ReportLog [this=%p]", this); + const bool testMode = + StaticPrefs::telemetry_origin_telemetry_test_mode_enabled(); + OriginMetricID metricId = + testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly + : OriginMetricID::ContentBlocking_Blocked; + ReportOriginSingleHash(metricId, kDummyOriginHash); for (const auto& originEntry : mLog) { if (!originEntry.mData) { @@ -126,12 +135,9 @@ void ContentBlockingLog::ReportLog() { const bool isBlocked = logEntry.mBlocked; Maybe reason = logEntry.mReason; - const bool testMode = - StaticPrefs::telemetry_origin_telemetry_test_mode_enabled(); - OriginMetricID metricId = - testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly - : OriginMetricID::ContentBlocking_Blocked; + metricId = testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly + : OriginMetricID::ContentBlocking_Blocked; if (!isBlocked) { MOZ_ASSERT(reason.isSome()); switch (reason.value()) { diff --git a/toolkit/components/telemetry/core/TelemetryOriginData.inc b/toolkit/components/telemetry/core/TelemetryOriginData.inc index f348b9af6af9..03b9337fbe60 100644 --- a/toolkit/components/telemetry/core/TelemetryOriginData.inc +++ b/toolkit/components/telemetry/core/TelemetryOriginData.inc @@ -1,3 +1,6 @@ +// dummy origin +ORIGIN("PAGELOAD", "PAGELOAD") + ORIGIN("advertstream.com", "lzPiT1FuoHNMKQ1Hw8AaTi68TokOB24ciFBqmCk62ek=") ORIGIN("kitaramedia.com", "r+U9PL3uMrjCKe8/T8goY9MHPA+6JckC3R+/1R9TQKA=") ORIGIN("questionmarket.com", "3KCO/qN+KmApmfH3RaXAmdR65Z/TRfrr6pds7aDKn1c=") diff --git a/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp b/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp index dd83354501cc..56ab3a4f4319 100644 --- a/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp @@ -20,6 +20,26 @@ using ::testing::_; using ::testing::AtLeast; using ::testing::StrEq; +NS_NAMED_LITERAL_CSTRING(kTelemetryTest1Metric, "telemetry.test_test1"); + +NS_NAMED_LITERAL_CSTRING(kDummyOrigin, "PAGELOAD"); +NS_NAMED_LITERAL_CSTRING(kDoubleclickOrigin, "doubleclick.net"); +NS_NAMED_LITERAL_CSTRING(kDoubleclickOriginHash, + "uXNT1PzjAVau8b402OMAIGDejKbiXfQX5iXvPASfO/s="); +NS_NAMED_LITERAL_CSTRING(kFacebookOrigin, "fb.com"); +NS_NAMED_LITERAL_CSTRING(kUnknownOrigin1, + "this origin isn't known to Origin Telemetry"); +NS_NAMED_LITERAL_CSTRING(kUnknownOrigin2, "neither is this one"); + +// Properly prepare the prio prefs +// (Sourced from PrioEncoder.cpp from when it was being prototyped) +NS_NAMED_LITERAL_CSTRING( + prioKeyA, + "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); +NS_NAMED_LITERAL_CSTRING( + prioKeyB, + "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); + // Test that we can properly record origin stuff using the C++ API. TEST_F(TelemetryTestFixture, RecordOrigin) { AutoJSContextWithGlobal cx(mCleanGlobal); @@ -27,10 +47,7 @@ TEST_F(TelemetryTestFixture, RecordOrigin) { Unused << mTelemetry->ClearOrigins(); - const nsLiteralCString doubleclick("doubleclick.net"); - const nsLiteralCString telemetryTest1("telemetry.test_test1"); - - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kDummyOrigin); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot); @@ -40,12 +57,13 @@ TEST_F(TelemetryTestFixture, RecordOrigin) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) + ASSERT_TRUE( + JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); + ASSERT_TRUE(JS_GetProperty(aCx, originsObj, kDummyOrigin.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 1) << "Must have recorded the origin exactly once."; @@ -64,11 +82,10 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceAndClear) { Unused << mTelemetry->ClearOrigins(); - const nsLiteralCString doubleclick("doubleclick.net"); - const nsLiteralCString telemetryTest1("telemetry.test_test1"); - - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOrigin); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOrigin); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot, true /* aClear */); @@ -78,12 +95,14 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceAndClear) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) + ASSERT_TRUE( + JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); + ASSERT_TRUE( + JS_GetProperty(aCx, originsObj, kDoubleclickOrigin.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 2) << "Must have recorded the origin exactly twice."; @@ -102,26 +121,17 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceMixed) { Unused << mTelemetry->ClearOrigins(); - const nsLiteralCString doubleclick("doubleclick.net"); - const nsLiteralCString doubleclickHash( - "uXNT1PzjAVau8b402OMAIGDejKbiXfQX5iXvPASfO/s="); - const nsLiteralCString telemetryTest1("telemetry.test_test1"); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOrigin); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOriginHash); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclickHash); - - // Properly prepare the prio prefs - // (Sourced from PrioEncoder.cpp from when it was being prototyped) - const nsLiteralCString prioKeyA( - "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); - const nsLiteralCString prioKeyB( - "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); Preferences::SetCString("prio.publicKeyA", prioKeyA); Preferences::SetCString("prio.publicKeyB", prioKeyB); nsTArray> encodedStrings; - GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), - encodedStrings); + GetEncodedOriginStrings( + aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), encodedStrings); ASSERT_EQ(2 * TelemetryOrigin::SizeOfPrioDatasPerMetric(), encodedStrings.Length()); @@ -133,12 +143,14 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceMixed) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) + ASSERT_TRUE( + JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); + ASSERT_TRUE( + JS_GetProperty(aCx, originsObj, kDoubleclickOrigin.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 2) << "Must have recorded the origin exactly twice."; } @@ -149,11 +161,7 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { Unused << mTelemetry->ClearOrigins(); - const nsLiteralCString telemetryTest1("telemetry.test_test1"); - const nsLiteralCString unknown("this origin isn't known to Origin Telemetry"); - const nsLiteralCString unknown2("neither is this one"); - - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin1); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot); @@ -163,7 +171,8 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) + ASSERT_TRUE( + JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); @@ -173,7 +182,7 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { << "Must have recorded the unknown origin exactly once."; // Record a second, different unknown origin and ensure only one is stored. - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown2); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin2); GetOriginSnapshot(aCx, &originSnapshot); @@ -181,7 +190,8 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { << "Origin snapshot must not be null/undefined."; JS::RootedObject snapshotObj2(aCx, &originSnapshot.toObject()); - ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj2, telemetryTest1.get(), &origins)) + ASSERT_TRUE( + JS_GetProperty(aCx, snapshotObj2, kTelemetryTest1Metric.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj2(aCx, &origins.toObject()); @@ -197,30 +207,21 @@ TEST_F(TelemetryTestFixture, EncodedSnapshot) { Unused << mTelemetry->ClearOrigins(); - const nsLiteralCString doubleclick("doubleclick.net"); - const nsLiteralCString unknown("this origin isn't known to Origin Telemetry"); - const nsLiteralCString telemetryTest1("telemetry.test_test1"); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOrigin); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin1); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown); - - // Properly prepare the prio prefs - // (Sourced from PrioEncoder.cpp from when it was being prototyped) - const nsLiteralCString prioKeyA( - "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); - const nsLiteralCString prioKeyB( - "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); Preferences::SetCString("prio.publicKeyA", prioKeyA); Preferences::SetCString("prio.publicKeyB", prioKeyB); nsTArray> firstStrings; - GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), - firstStrings); + GetEncodedOriginStrings( + aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), firstStrings); // Now snapshot a second time and ensure the encoded payloads change. nsTArray> secondStrings; - GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), - secondStrings); + GetEncodedOriginStrings( + aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), secondStrings); const auto sizeOfPrioDatasPerMetric = TelemetryOrigin::SizeOfPrioDatasPerMetric(); @@ -265,8 +266,6 @@ TEST_F(TelemetryTestFixture, OriginTelemetryNotifiesTopic) { Unused << mTelemetry->ClearOrigins(); const char* kTopic = "origin-telemetry-storage-limit-reached"; - NS_NAMED_LITERAL_CSTRING(doubleclick, "doubleclick.net"); - NS_NAMED_LITERAL_CSTRING(fb, "fb.com"); MockObserver* mo = new MockObserver(); nsCOMPtr nsMo(mo); @@ -280,9 +279,11 @@ TEST_F(TelemetryTestFixture, OriginTelemetryNotifiesTopic) { for (size_t i = 0; i < size; ++i) { if (i < size - 1) { // Let's ensure we only notify the once. - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, fb); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kFacebookOrigin); } - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, + kDoubleclickOrigin); } os->RemoveObserver(nsMo, kTopic); From 2da1acaef86b04b7649d951534ccd13882520f63 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 20 May 2019 14:29:15 +0000 Subject: [PATCH 002/129] Bug 1509423 - Disable the gfxCoreText backend and use native HarfBuzz shaping for AAT fonts. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D31094 --HG-- extra : moz-landing-system : lando --- gfx/thebes/gfxMacFont.cpp | 4 +++- gfx/thebes/gfxPlatform.cpp | 7 +++++++ gfx/thebes/gfxPrefs.h | 3 +++ modules/libpref/init/all.js | 5 +++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxMacFont.cpp b/gfx/thebes/gfxMacFont.cpp index 61eeaebe4812..60b869af14c3 100644 --- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -16,6 +16,7 @@ #include "gfxFontUtils.h" #include "gfxMacPlatformFontList.h" #include "gfxFontConstants.h" +#include "gfxPrefs.h" #include "gfxTextRun.h" #include "nsCocoaFeatures.h" @@ -199,7 +200,8 @@ bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText, // Currently, we don't support vertical shaping via CoreText, // so we ignore RequiresAATLayout if vertical is requested. auto macFontEntry = static_cast(GetFontEntry()); - if (macFontEntry->RequiresAATLayout() && !aVertical) { + if (macFontEntry->RequiresAATLayout() && !aVertical && + gfxPrefs::CoreTextEnabled()) { if (!mCoreTextShaper) { mCoreTextShaper = MakeUnique(this); } diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 5220245cc936..02e53089d917 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -409,6 +409,9 @@ NS_IMPL_ISUPPORTS(SRGBOverrideObserver, nsIObserver, nsISupportsWeakReference) #define GFX_PREF_WORD_CACHE_MAXENTRIES "gfx.font_rendering.wordcache.maxentries" #define GFX_PREF_GRAPHITE_SHAPING "gfx.font_rendering.graphite.enabled" +#if defined(XP_MACOSX) +#define GFX_PREF_CORETEXT_SHAPING "gfx.font_rendering.coretext.enabled" +#endif #define BIDI_NUMERAL_PREF "bidi.numeral" @@ -2216,6 +2219,10 @@ void gfxPlatform::FontsPrefsChanged(const char* aPref) { } else if (!strcmp(GFX_PREF_GRAPHITE_SHAPING, aPref)) { mGraphiteShapingEnabled = UNINITIALIZED_VALUE; FlushFontAndWordCaches(); +#if defined(XP_MACOSX) + } else if (!strcmp(GFX_PREF_CORETEXT_SHAPING, aPref)) { + FlushFontAndWordCaches(); +#endif } else if (!strcmp(BIDI_NUMERAL_PREF, aPref)) { mBidiNumeralOption = UNINITIALIZED_VALUE; } else if (!strcmp(GFX_PREF_OPENTYPE_SVG, aPref)) { diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index a31b1f070503..9eae349a199b 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -498,6 +498,9 @@ class gfxPrefs final { DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false); DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll", HidePluginsForScroll, bool, true); DECL_GFX_PREF(Once, "gfx.e10s.font-list.shared", SharedFontList, bool, false); +#if defined(XP_MACOSX) + DECL_GFX_PREF(Live, "gfx.font_rendering.coretext.enabled", CoreTextEnabled, bool, false); +#endif DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false); DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456); // Note that "gfx.logging.level" is defined in Logging.h. diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 7e7b06bb80d2..09db78d7f808 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -853,6 +853,11 @@ pref("gfx.font_rendering.wordcache.maxentries", 10000); pref("gfx.font_rendering.graphite.enabled", true); +#ifdef XP_MACOSX +// Set to true to revert from HarfBuzz AAT shaping to the old Core Text backend +pref("gfx.font_rendering.coretext.enabled", false); +#endif + #ifdef XP_WIN pref("gfx.font_rendering.directwrite.use_gdi_table_loading", true); #endif From 35bcd113af647633e7deb31f99624280e6ce4bfa Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 20 May 2019 14:29:35 +0000 Subject: [PATCH 003/129] Bug 1509423 - Test/manifest updates to account for minor rendering differences between HarfBuzz and Core Text. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D31095 --HG-- extra : moz-landing-system : lando --- layout/generic/test/test_selection_expanding.html | 2 +- layout/reftests/bugs/reftest.list | 4 ++-- layout/reftests/line-breaking/reftest.list | 2 +- layout/reftests/mathml/reftest.list | 4 ++-- layout/reftests/svg/reftest.list | 2 +- layout/reftests/svg/svg-integration/reftest.list | 2 +- layout/reftests/svg/text/reftest.list | 8 ++++---- layout/reftests/text-stroke/reftest.list | 6 +++--- .../web-platform/meta/css/CSS2/bidi-text/bidi-001.xht.ini | 3 +++ .../web-platform/meta/css/CSS2/bidi-text/bidi-002.xht.ini | 3 +++ .../meta/css/CSS2/css1/c43-rpl-ibx-000.xht.ini | 1 - .../css/CSS2/floats-clear/clear-applies-to-008.xht.ini | 3 --- ...tain-paint-independent-formatting-context-002.html.ini | 3 --- .../css/css-display/display-contents-details.html.ini | 4 ---- .../css/css-display/display-contents-fieldset.html.ini | 3 --- .../multi-line-wrap-reverse-column-reverse.html.ini | 5 ----- .../multi-line-wrap-with-column-reverse.html.ini | 4 ---- .../css/css-text-decor/text-emphasis-style-006.html.ini | 2 ++ .../css-text/word-break/word-break-break-all-004.html.ini | 3 --- .../tests/css/css-display/display-contents-details.html | 1 + 20 files changed, 24 insertions(+), 41 deletions(-) create mode 100644 testing/web-platform/meta/css/CSS2/bidi-text/bidi-001.xht.ini create mode 100644 testing/web-platform/meta/css/CSS2/bidi-text/bidi-002.xht.ini delete mode 100644 testing/web-platform/meta/css/CSS2/floats-clear/clear-applies-to-008.xht.ini delete mode 100644 testing/web-platform/meta/css/css-contain/contain-paint-independent-formatting-context-002.html.ini delete mode 100644 testing/web-platform/meta/css/css-display/display-contents-details.html.ini delete mode 100644 testing/web-platform/meta/css/css-display/display-contents-fieldset.html.ini delete mode 100644 testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html.ini delete mode 100644 testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-with-column-reverse.html.ini delete mode 100644 testing/web-platform/meta/css/css-text/word-break/word-break-break-all-004.html.ini diff --git a/layout/generic/test/test_selection_expanding.html b/layout/generic/test/test_selection_expanding.html index b9d187ad7910..e6e5eb3b5420 100644 --- a/layout/generic/test/test_selection_expanding.html +++ b/layout/generic/test/test_selection_expanding.html @@ -346,7 +346,7 @@ function test() // *********************************************************** // selection starting at iframe - synthesizeMouse(iframe, 30, 5, { type: "mousedown" }); + synthesizeMouse(iframe, 20, 5, { type: "mousedown" }); // inside iframe synthesizeMouse(iframe, 50, 5, { type: "mousemove" }); diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index bcd65bcc9258..10b3f6676341 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1328,7 +1328,7 @@ fails-if(Android) == 481024-1c.html 481024-1-ref.html == 481024-1e.html 481024-1-ref.html != 481948-1.html 481948-1-ref.html != 481948-2.html 481948-2-ref.html -fails-if(Android||gtkWidget) random-if(winWidget) == 481948-3.html 481948-3-ref.html # questionable test, see bug 488364 +fails-if(Android||gtkWidget) random-if(winWidget||cocoaWidget) == 481948-3.html 481948-3-ref.html # questionable test, see bug 488364 == 482398-1.html 482398-1-ref.html random-if(d2d) == 482592-1a.xhtml 482592-1-ref.html # bug 586771 random-if(d2d) == 482592-1b.xhtml 482592-1-ref.html # bug 586771 @@ -1425,7 +1425,7 @@ fuzzy-if(Android,0-5,0-1656) fuzzy-if(skiaContent,0-1,0-1200) == 512410.html 512 == 512631-1.html 512631-1-ref.html == 513153-1a.html 513153-1-ref.html == 513153-1b.html 513153-1-ref.html -fuzzy-if(webrender&&winWidget,82-82,76-76) == 513153-2a.html 513153-2-ref.html +fuzzy-if(webrender&&winWidget,82-82,76-76) fuzzy-if(webrender&&cocoaWidget,0-34,0-103) == 513153-2a.html 513153-2-ref.html fuzzy-if(webrender&&cocoaWidget,34-34,103-103) == 513153-2b.html 513153-2-ref.html == 513318-1.xul 513318-1-ref.xul fails-if(Android&&(!asyncPan)) != 513318-2.xul 513318-2-ref.xul diff --git a/layout/reftests/line-breaking/reftest.list b/layout/reftests/line-breaking/reftest.list index a59f7bda1785..689122608966 100644 --- a/layout/reftests/line-breaking/reftest.list +++ b/layout/reftests/line-breaking/reftest.list @@ -33,7 +33,7 @@ skip-if(gtkWidget) == quotationmarks-cjk-1.html quotationmarks-cjk-1-ref.html == smileys-1.html smileys-1-ref.html == smileys-2.html smileys-2-ref.html == space-cluster-1.html space-cluster-1-ref.html -== space-cluster-2.html space-cluster-2-ref.html +random-if(cocoaWidget) == space-cluster-2.html space-cluster-2-ref.html # harfbuzz vs coretext, different positioning of stray diacritics == surrogates-1.html surrogates-1-ref.html == surrogates-2.html surrogates-2-ref.html == surrogates-3.html surrogates-3-ref.html diff --git a/layout/reftests/mathml/reftest.list b/layout/reftests/mathml/reftest.list index 0774f3c33afc..532a7cee3c6e 100644 --- a/layout/reftests/mathml/reftest.list +++ b/layout/reftests/mathml/reftest.list @@ -3,8 +3,8 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == dir-2.html dir-2-ref.htm random-if(gtkWidget) == dir-3.html dir-3-ref.html # bug 1309426 == dir-4.html dir-4-ref.html == dir-5.html dir-5-ref.html -== dir-6.html dir-6-ref.html -== dir-6a.html dir-6a-ref.html +fuzzy-if(cocoaWidget,0-135,0-56) == dir-6.html dir-6-ref.html +fuzzy-if(cocoaWidget,0-135,0-56) == dir-6a.html dir-6a-ref.html random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == dir-7.html dir-7-ref.html # Bug 1392106 fails == dir-8.html dir-8-ref.html fails == dir-9.html dir-9-ref.html # Bug 787215 diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index d76646bfe9aa..c6141ea6c2fa 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -211,7 +211,7 @@ skip pref(security.fileuri.strict_origin_policy,true) == filter-extref-different == filter-foreignObject-01.svg pass.svg == filter-in-mask-01.svg pass.svg == filter-invalidation-01.svg pass.svg -fuzzy(0-71,0-817) fails-if(winWidget) fuzzy-if(webrender&&cocoaWidget,67-67,887-887) == filter-on-continuation-box-01.html filter-on-continuation-box-ref.html +fuzzy(0-71,0-821) fails-if(winWidget) fuzzy-if(webrender&&cocoaWidget,67-67,887-892) == filter-on-continuation-box-01.html filter-on-continuation-box-ref.html == filter-result-01.svg filter-result-01-ref.svg == filter-scaled-01.svg pass.svg fuzzy-if(skiaContent,0-1,0-500) == filter-scaled-02.html filter-scaled-02-ref.html diff --git a/layout/reftests/svg/svg-integration/reftest.list b/layout/reftests/svg/svg-integration/reftest.list index 167f62f8381d..b539f65dc128 100644 --- a/layout/reftests/svg/svg-integration/reftest.list +++ b/layout/reftests/svg/svg-integration/reftest.list @@ -48,5 +48,5 @@ fuzzy(0-1,0-5000) == mask-clipPath-opacity-01e.xhtml mask-clipPath-opacity-01-re # box-decoration-break tests fuzzy-if(Android,0-4,0-10) fuzzy-if(webrender&&cocoaWidget,9-9,3-3) == box-decoration-break-01.xhtml box-decoration-break-01-ref.xhtml -fuzzy(0-62,0-14) == box-decoration-break-02.xhtml box-decoration-break-02-ref.xhtml +fuzzy(0-119,0-16) == box-decoration-break-02.xhtml box-decoration-break-02-ref.xhtml fuzzy(0-67,0-238) == box-decoration-break-03.xhtml box-decoration-break-01-ref.xhtml diff --git a/layout/reftests/svg/text/reftest.list b/layout/reftests/svg/text/reftest.list index eafb50a847c9..94e6f98c6396 100644 --- a/layout/reftests/svg/text/reftest.list +++ b/layout/reftests/svg/text/reftest.list @@ -4,8 +4,8 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender&&!gtkWid random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-scaled.svg simple-underline-scaled-ref.svg # Bug 1392106 fuzzy-if(webrender&&!gtkWidget,119-166,255-318) == simple-anchor-end-bidi.svg simple-anchor-end-bidi-ref.html fuzzy-if(webrender&&!gtkWidget,117-138,182-204) == simple-anchor-end-rtl.svg simple-anchor-end-rtl-ref.html -fuzzy-if(webrender&&!gtkWidget,122-137,220-250) == simple-anchor-end.svg simple-anchor-end-ref.html -fuzzy-if(skiaContent&&dwrite,0-104,0-131) fuzzy-if(webrender&&!gtkWidget,125-200,259-319) == simple-anchor-middle-bidi.svg simple-anchor-middle-bidi-ref.html +fuzzy-if(webrender&&!gtkWidget,119-137,220-250) == simple-anchor-end.svg simple-anchor-end-ref.html +fuzzy-if(skiaContent&&dwrite,0-104,0-131) fuzzy-if(cocoaWidget,0-143,0-124) fuzzy-if(webrender&&!gtkWidget,125-200,259-319) == simple-anchor-middle-bidi.svg simple-anchor-middle-bidi-ref.html fuzzy-if(webrender&&!gtkWidget,132-138,188-207) == simple-anchor-middle-rtl.svg simple-anchor-middle-rtl-ref.html fuzzy-if(skiaContent,0-111,0-81) fuzzy-if(webrender&&!gtkWidget,122-181,221-257) == simple-anchor-middle.svg simple-anchor-middle-ref.html fuzzy-if(webrender&&!gtkWidget,132-138,261-319) == simple-bidi.svg simple-bidi-ref.html @@ -196,10 +196,10 @@ needs-focus == deselectAll.svg deselectAll-ref.svg fuzzy-if(skiaContent,0-1,0-250) needs-focus == selectSubString.svg selectSubString-ref.svg fuzzy-if(skiaContent,0-1,0-600) needs-focus == selectSubString-2.svg selectSubString-2-ref.svg fuzzy-if(skiaContent,0-1,0-250) needs-focus == selectSubString-3.svg selectSubString-3-ref.svg -random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender,1-1,237-237) needs-focus fuzzy-if(webrender&&!gtkWidget,127-148,221-254) == simple-selection.svg simple-selection-ref.html # Bug 1392106 +random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender,1-1,237-237) needs-focus fuzzy-if(webrender&&!gtkWidget,125-148,221-254) == simple-selection.svg simple-selection-ref.html # Bug 1392106 fuzzy-if(skiaContent,0-1,0-100) fuzzy-if(webrender,1-1,575-575) needs-focus fuzzy-if(webrender&&!gtkWidget,134-148,261-318) == simple-bidi-selection.svg simple-bidi-selection-ref.html fuzzy-if(skiaContent,0-1,0-50) fuzzy-if(webrender,1-1,237-237) needs-focus fuzzy-if(webrender&&!gtkWidget,127-148,221-254) == simple-fill-color-selection.svg simple-fill-color-selection-ref.html -fuzzy-if(skiaContent,0-1,0-150) fuzzy-if(webrender,1-1,222-222) needs-focus fuzzy-if(webrender&&!gtkWidget,127-148,221-254) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-selection.svg simple-underline-selection-ref.html # Bug 1392106 +fuzzy-if(skiaContent,0-1,0-150) fuzzy-if(webrender,1-1,222-222) needs-focus fuzzy-if(webrender&&!gtkWidget,125-148,221-254) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-selection.svg simple-underline-selection-ref.html # Bug 1392106 fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender,1-1,934-934) needs-focus fuzzy-if(webrender&&!gtkWidget,134-152,432-501) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == multiple-text-selection.svg multiple-text-selection-ref.html # Bug 1392106 needs-focus == multiple-chunks-selection.svg multiple-chunks-selection-ref.svg fuzzy-if(skiaContent,0-1,0-200) needs-focus == textpath-selection.svg textpath-selection-ref.svg diff --git a/layout/reftests/text-stroke/reftest.list b/layout/reftests/text-stroke/reftest.list index 52407d35fdb3..e4eba563319b 100644 --- a/layout/reftests/text-stroke/reftest.list +++ b/layout/reftests/text-stroke/reftest.list @@ -3,9 +3,9 @@ default-preferences pref(layout.css.prefixes.webkit,true) # These fail on Linux without webrender due to lack of antialiasing of the HTML text stroke -fuzzy(0-64,0-44) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html +fuzzy(0-64,0-46) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html fuzzy(0-4,0-24) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-002.html webkit-text-stroke-property-002-ref.html -fuzzy(0-48,0-26) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html +fuzzy(0-48,0-28) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html fuzzy(0-64,0-33) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-004.html webkit-text-stroke-property-004-ref.html -fuzzy(0-64,0-44) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html +fuzzy(0-64,0-46) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html fuzzy(0-71,0-10) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-006.html webkit-text-stroke-property-006-ref.html diff --git a/testing/web-platform/meta/css/CSS2/bidi-text/bidi-001.xht.ini b/testing/web-platform/meta/css/CSS2/bidi-text/bidi-001.xht.ini new file mode 100644 index 000000000000..f5aab79f77ea --- /dev/null +++ b/testing/web-platform/meta/css/CSS2/bidi-text/bidi-001.xht.ini @@ -0,0 +1,3 @@ +[bidi-001.xht] + fuzzy: + if os == "mac": maxDifference=3;totalPixels=0-1 diff --git a/testing/web-platform/meta/css/CSS2/bidi-text/bidi-002.xht.ini b/testing/web-platform/meta/css/CSS2/bidi-text/bidi-002.xht.ini new file mode 100644 index 000000000000..a606245391fd --- /dev/null +++ b/testing/web-platform/meta/css/CSS2/bidi-text/bidi-002.xht.ini @@ -0,0 +1,3 @@ +[bidi-002.xht] + fuzzy: + if os == "mac": maxDifference=1;totalPixels=0-1 diff --git a/testing/web-platform/meta/css/CSS2/css1/c43-rpl-ibx-000.xht.ini b/testing/web-platform/meta/css/CSS2/css1/c43-rpl-ibx-000.xht.ini index 35dec9c4d2bf..cf2293fca384 100644 --- a/testing/web-platform/meta/css/CSS2/css1/c43-rpl-ibx-000.xht.ini +++ b/testing/web-platform/meta/css/CSS2/css1/c43-rpl-ibx-000.xht.ini @@ -1,5 +1,4 @@ [c43-rpl-ibx-000.xht] expected: - if os == "mac": FAIL if (os == "android") and not e10s: FAIL if (os == "android") and e10s: FAIL diff --git a/testing/web-platform/meta/css/CSS2/floats-clear/clear-applies-to-008.xht.ini b/testing/web-platform/meta/css/CSS2/floats-clear/clear-applies-to-008.xht.ini deleted file mode 100644 index 2e006a9b0d04..000000000000 --- a/testing/web-platform/meta/css/CSS2/floats-clear/clear-applies-to-008.xht.ini +++ /dev/null @@ -1,3 +0,0 @@ -[clear-applies-to-008.xht] - expected: - if (os == "mac"): FAIL diff --git a/testing/web-platform/meta/css/css-contain/contain-paint-independent-formatting-context-002.html.ini b/testing/web-platform/meta/css/css-contain/contain-paint-independent-formatting-context-002.html.ini deleted file mode 100644 index 4cf4d64a1910..000000000000 --- a/testing/web-platform/meta/css/css-contain/contain-paint-independent-formatting-context-002.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[contain-paint-independent-formatting-context-002.html] - expected: - if (os == "mac"): FAIL diff --git a/testing/web-platform/meta/css/css-display/display-contents-details.html.ini b/testing/web-platform/meta/css/css-display/display-contents-details.html.ini deleted file mode 100644 index bd1f88b4e7e2..000000000000 --- a/testing/web-platform/meta/css/css-display/display-contents-details.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[display-contents-details.html] - expected: - if (os == "mac"): PASS - FAIL diff --git a/testing/web-platform/meta/css/css-display/display-contents-fieldset.html.ini b/testing/web-platform/meta/css/css-display/display-contents-fieldset.html.ini deleted file mode 100644 index 1c0e7423700c..000000000000 --- a/testing/web-platform/meta/css/css-display/display-contents-fieldset.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[display-contents-fieldset.html] - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html.ini b/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html.ini deleted file mode 100644 index 3ba3d26c6671..000000000000 --- a/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-reverse-column-reverse.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[multi-line-wrap-reverse-column-reverse.html] - expected: - if (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL - if (os == "mac") and (version == "OS X 10.14") and (processor == "x86_64") and (bits == 64): FAIL - \ No newline at end of file diff --git a/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-with-column-reverse.html.ini b/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-with-column-reverse.html.ini deleted file mode 100644 index d06595bf7178..000000000000 --- a/testing/web-platform/meta/css/css-flexbox/flex-lines/multi-line-wrap-with-column-reverse.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[multi-line-wrap-with-column-reverse.html] - expected: - if (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL - if (os == "mac") and (version == "OS X 10.14") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/css/css-text-decor/text-emphasis-style-006.html.ini b/testing/web-platform/meta/css/css-text-decor/text-emphasis-style-006.html.ini index 793080fd905b..8f63b06b8583 100644 --- a/testing/web-platform/meta/css/css-text-decor/text-emphasis-style-006.html.ini +++ b/testing/web-platform/meta/css/css-text-decor/text-emphasis-style-006.html.ini @@ -1,3 +1,5 @@ [text-emphasis-style-006.html] disabled: if (os == "android") and e10s: bug 1550895 (frequently fails on geckoview) + fuzzy: + if os == "mac": maxDifference=96;totalPixels=0-12 diff --git a/testing/web-platform/meta/css/css-text/word-break/word-break-break-all-004.html.ini b/testing/web-platform/meta/css/css-text/word-break/word-break-break-all-004.html.ini deleted file mode 100644 index 7d42ee5ee3b9..000000000000 --- a/testing/web-platform/meta/css/css-text/word-break/word-break-break-all-004.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[word-break-break-all-004.html] - expected: - if (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/tests/css/css-display/display-contents-details.html b/testing/web-platform/tests/css/css-display/display-contents-details.html index b6a6540f0139..0dcda91ab380 100644 --- a/testing/web-platform/tests/css/css-display/display-contents-details.html +++ b/testing/web-platform/tests/css/css-display/display-contents-details.html @@ -5,6 +5,7 @@ +
abcdefg
+
LMNOPQR
diff --git a/layout/reftests/text-svgglyphs/svg-glyph-compressed.html b/layout/reftests/text-svgglyphs/svg-glyph-compressed.html new file mode 100644 index 000000000000..0c51a54b1236 --- /dev/null +++ b/layout/reftests/text-svgglyphs/svg-glyph-compressed.html @@ -0,0 +1,13 @@ + +Test for compressed SVG glyphs + +
abcdefg
+
LMNOPQR
From 0c8c03610cd975b2aea1e17754d7ad297848f38b Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 20 May 2019 14:34:10 +0000 Subject: [PATCH 008/129] Bug 1552199 - Include records from dump in Remote Settings sync event created data r=glasserc Differential Revision: https://phabricator.services.mozilla.com/D31599 --HG-- extra : moz-landing-system : lando --- services/settings/RemoteSettingsClient.jsm | 10 +- .../test/unit/test_remote_settings.js | 117 +++++++++++++----- 2 files changed, 92 insertions(+), 35 deletions(-) diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm index 9afd2787ade2..cdc595e0231c 100644 --- a/services/settings/RemoteSettingsClient.jsm +++ b/services/settings/RemoteSettingsClient.jsm @@ -282,6 +282,7 @@ class RemoteSettingsClient extends EventEmitter { async maybeSync(expectedTimestamp, options = {}) { const { loadDump = true, trigger = "manual" } = options; + let importedFromDump = []; const startedAt = new Date(); let reportStatus = null; try { @@ -295,7 +296,11 @@ class RemoteSettingsClient extends EventEmitter { // cold start. if (!collectionLastModified && loadDump) { try { - await RemoteSettingsWorker.importJSONDump(this.bucketName, this.collectionName); + const imported = await RemoteSettingsWorker.importJSONDump(this.bucketName, this.collectionName); + // The worker only returns an integer. List the imported records to build the sync event. + if (imported > 0) { + ({ data: importedFromDump } = await kintoCollection.list()); + } collectionLastModified = await kintoCollection.db.getLastModified(); } catch (e) { // Report but go-on. @@ -337,6 +342,9 @@ class RemoteSettingsClient extends EventEmitter { // With SERVER_WINS, there cannot be any conflicts, but don't silent it anyway. throw new Error("Synced failed"); } + // The records imported from the dump should be considered as "created" for the + // listeners. + syncResult.created = importedFromDump.concat(syncResult.created); } catch (e) { if (e instanceof RemoteSettingsClient.InvalidSignatureError) { // Signature verification failed during synchronization. diff --git a/services/settings/test/unit/test_remote_settings.js b/services/settings/test/unit/test_remote_settings.js index e268371c56a8..d56117813bf7 100644 --- a/services/settings/test/unit/test_remote_settings.js +++ b/services/settings/test/unit/test_remote_settings.js @@ -51,39 +51,12 @@ function run_test() { clientWithDump = RemoteSettings("language-dictionaries"); clientWithDump.verifySignature = false; - // Setup server fake responses. - function handleResponse(request, response) { - try { - const sample = getSampleResponse(request, server.identity.primaryPort); - if (!sample) { - do_throw(`unexpected ${request.method} request for ${request.path}?${request.queryString}`); - } - - response.setStatusLine(null, sample.status.status, - sample.status.statusText); - // send the headers - for (let headerLine of sample.sampleHeaders) { - let headerElements = headerLine.split(":"); - response.setHeader(headerElements[0], headerElements[1].trimLeft()); - } - response.setHeader("Date", (new Date()).toUTCString()); - - const body = typeof sample.responseBody == "string" ? sample.responseBody - : JSON.stringify(sample.responseBody); - response.write(body); - response.finish(); - } catch (e) { - info(e); - } - } - const configPath = "/v1/"; - const changesPath = "/v1/buckets/monitor/collections/changes/records"; - const metadataPath = "/v1/buckets/main/collections/password-fields"; - const recordsPath = "/v1/buckets/main/collections/password-fields/records"; - server.registerPathHandler(configPath, handleResponse); - server.registerPathHandler(changesPath, handleResponse); - server.registerPathHandler(metadataPath, handleResponse); - server.registerPathHandler(recordsPath, handleResponse); + server.registerPathHandler("/v1/", handleResponse); + server.registerPathHandler("/v1/buckets/monitor/collections/changes/records", handleResponse); + server.registerPathHandler("/v1/buckets/main/collections/password-fields", handleResponse); + server.registerPathHandler("/v1/buckets/main/collections/password-fields/records", handleResponse); + server.registerPathHandler("/v1/buckets/main/collections/language-dictionaries", handleResponse); + server.registerPathHandler("/v1/buckets/main/collections/language-dictionaries/records", handleResponse); server.registerPathHandler("/fake-x5u", handleResponse); run_next_test(); @@ -104,6 +77,22 @@ add_task(async function test_records_obtained_from_server_are_stored_in_db() { }); add_task(clear_state); +add_task(async function test_records_from_dump_are_listed_as_created_in_event() { + let received; + clientWithDump.on("sync", ({ data }) => received = data); + // Use a timestamp superior to latest record in dump. + const timestamp = 5000000000000; // Fri Jun 11 2128 + + await clientWithDump.maybeSync(timestamp); + + const list = await clientWithDump.get(); + ok(list.length > 20, "The dump was loaded"); + equal(received.created[received.created.length - 1].id, "xx", "Last record comes from the sync."); + equal(received.created.length, list.length, "The list of created records contains the dump"); + equal(received.current.length, received.created.length); +}); +add_task(clear_state); + add_task(async function test_records_can_have_local_fields() { const c = RemoteSettings("password-fields", { localFields: ["accepted"] }); await c.maybeSync(2000); @@ -487,7 +476,30 @@ add_task(async function test_inspect_changes_the_list_when_bucket_pref_is_change }); add_task(clear_state); -// get a response for a given request from sample data +function handleResponse(request, response) { + try { + const sample = getSampleResponse(request, server.identity.primaryPort); + if (!sample) { + do_throw(`unexpected ${request.method} request for ${request.path}?${request.queryString}`); + } + + response.setStatusLine(null, sample.status.status, sample.status.statusText); + // send the headers + for (let headerLine of sample.sampleHeaders) { + let headerElements = headerLine.split(":"); + response.setHeader(headerElements[0], headerElements[1].trimLeft()); + } + response.setHeader("Date", (new Date()).toUTCString()); + + const body = typeof sample.responseBody == "string" ? sample.responseBody + : JSON.stringify(sample.responseBody); + response.write(body); + response.finish(); + } catch (e) { + info(e); + } +} + function getSampleResponse(req, port) { const responses = { "OPTIONS": { @@ -741,6 +753,43 @@ wNuvFqc= }], }, }, + "GET:/v1/buckets/main/collections/language-dictionaries": { + "sampleHeaders": [ + "Access-Control-Allow-Origin: *", + "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff", + "Content-Type: application/json; charset=UTF-8", + "Server: waitress", + "Etag: \"1234\"", + ], + "status": { status: 200, statusText: "OK" }, + "responseBody": JSON.stringify({ + "data": { + "id": "language-dictionaries", + "last_modified": 1234, + "signature": { + "signature": "xyz", + "x5u": `http://localhost:${port}/fake-x5u`, + }, + }, + }), + }, + "GET:/v1/buckets/main/collections/language-dictionaries/records": { + "sampleHeaders": [ + "Access-Control-Allow-Origin: *", + "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff", + "Content-Type: application/json; charset=UTF-8", + "Server: waitress", + "Etag: \"5000000000000\"", + ], + "status": { status: 200, statusText: "OK" }, + "responseBody": { + "data": [{ + "id": "xx", + "last_modified": 5000000000000, + "dictionaries": ["xx-XX@dictionaries.addons.mozilla.org"], + }], + }, + }, "GET:/v1/buckets/monitor/collections/changes/records?collection=no-mocked-responses&bucket=main": { "sampleHeaders": [ "Access-Control-Allow-Origin: *", From 8965da92035d8a3f330060db40cd445393b6b3f7 Mon Sep 17 00:00:00 2001 From: Bogdan Tara Date: Mon, 20 May 2019 17:49:27 +0300 Subject: [PATCH 009/129] Backed out changeset c77c46ac90a5 (bug 1552536) by xeonchen's request --- dom/base/ContentBlockingLog.cpp | 16 +-- .../telemetry/core/TelemetryOriginData.inc | 3 - .../telemetry/tests/gtest/TestOrigins.cpp | 117 +++++++++--------- 3 files changed, 63 insertions(+), 73 deletions(-) diff --git a/dom/base/ContentBlockingLog.cpp b/dom/base/ContentBlockingLog.cpp index 1bab0857c55f..f68c287ca9a1 100644 --- a/dom/base/ContentBlockingLog.cpp +++ b/dom/base/ContentBlockingLog.cpp @@ -21,9 +21,6 @@ typedef mozilla::Telemetry::OriginMetricID OriginMetricID; namespace mozilla { namespace dom { -// sync with TelemetryOriginData.inc -NS_NAMED_LITERAL_CSTRING(kDummyOriginHash, "PAGELOAD"); - // randomly choose 1% users included in the content blocking measurement // based on their client id. static constexpr double kRatioReportUser = 0.01; @@ -114,12 +111,6 @@ void ContentBlockingLog::ReportLog() { return; } LOG("ContentBlockingLog::ReportLog [this=%p]", this); - const bool testMode = - StaticPrefs::telemetry_origin_telemetry_test_mode_enabled(); - OriginMetricID metricId = - testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly - : OriginMetricID::ContentBlocking_Blocked; - ReportOriginSingleHash(metricId, kDummyOriginHash); for (const auto& originEntry : mLog) { if (!originEntry.mData) { @@ -135,9 +126,12 @@ void ContentBlockingLog::ReportLog() { const bool isBlocked = logEntry.mBlocked; Maybe reason = logEntry.mReason; + const bool testMode = + StaticPrefs::telemetry_origin_telemetry_test_mode_enabled(); - metricId = testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly - : OriginMetricID::ContentBlocking_Blocked; + OriginMetricID metricId = + testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly + : OriginMetricID::ContentBlocking_Blocked; if (!isBlocked) { MOZ_ASSERT(reason.isSome()); switch (reason.value()) { diff --git a/toolkit/components/telemetry/core/TelemetryOriginData.inc b/toolkit/components/telemetry/core/TelemetryOriginData.inc index 03b9337fbe60..f348b9af6af9 100644 --- a/toolkit/components/telemetry/core/TelemetryOriginData.inc +++ b/toolkit/components/telemetry/core/TelemetryOriginData.inc @@ -1,6 +1,3 @@ -// dummy origin -ORIGIN("PAGELOAD", "PAGELOAD") - ORIGIN("advertstream.com", "lzPiT1FuoHNMKQ1Hw8AaTi68TokOB24ciFBqmCk62ek=") ORIGIN("kitaramedia.com", "r+U9PL3uMrjCKe8/T8goY9MHPA+6JckC3R+/1R9TQKA=") ORIGIN("questionmarket.com", "3KCO/qN+KmApmfH3RaXAmdR65Z/TRfrr6pds7aDKn1c=") diff --git a/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp b/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp index 56ab3a4f4319..dd83354501cc 100644 --- a/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestOrigins.cpp @@ -20,26 +20,6 @@ using ::testing::_; using ::testing::AtLeast; using ::testing::StrEq; -NS_NAMED_LITERAL_CSTRING(kTelemetryTest1Metric, "telemetry.test_test1"); - -NS_NAMED_LITERAL_CSTRING(kDummyOrigin, "PAGELOAD"); -NS_NAMED_LITERAL_CSTRING(kDoubleclickOrigin, "doubleclick.net"); -NS_NAMED_LITERAL_CSTRING(kDoubleclickOriginHash, - "uXNT1PzjAVau8b402OMAIGDejKbiXfQX5iXvPASfO/s="); -NS_NAMED_LITERAL_CSTRING(kFacebookOrigin, "fb.com"); -NS_NAMED_LITERAL_CSTRING(kUnknownOrigin1, - "this origin isn't known to Origin Telemetry"); -NS_NAMED_LITERAL_CSTRING(kUnknownOrigin2, "neither is this one"); - -// Properly prepare the prio prefs -// (Sourced from PrioEncoder.cpp from when it was being prototyped) -NS_NAMED_LITERAL_CSTRING( - prioKeyA, - "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); -NS_NAMED_LITERAL_CSTRING( - prioKeyB, - "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); - // Test that we can properly record origin stuff using the C++ API. TEST_F(TelemetryTestFixture, RecordOrigin) { AutoJSContextWithGlobal cx(mCleanGlobal); @@ -47,7 +27,10 @@ TEST_F(TelemetryTestFixture, RecordOrigin) { Unused << mTelemetry->ClearOrigins(); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kDummyOrigin); + const nsLiteralCString doubleclick("doubleclick.net"); + const nsLiteralCString telemetryTest1("telemetry.test_test1"); + + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot); @@ -57,13 +40,12 @@ TEST_F(TelemetryTestFixture, RecordOrigin) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE( - JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) + ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE(JS_GetProperty(aCx, originsObj, kDummyOrigin.get(), &count)); + ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 1) << "Must have recorded the origin exactly once."; @@ -82,10 +64,11 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceAndClear) { Unused << mTelemetry->ClearOrigins(); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOrigin); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOrigin); + const nsLiteralCString doubleclick("doubleclick.net"); + const nsLiteralCString telemetryTest1("telemetry.test_test1"); + + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot, true /* aClear */); @@ -95,14 +78,12 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceAndClear) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE( - JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) + ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE( - JS_GetProperty(aCx, originsObj, kDoubleclickOrigin.get(), &count)); + ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 2) << "Must have recorded the origin exactly twice."; @@ -121,17 +102,26 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceMixed) { Unused << mTelemetry->ClearOrigins(); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOrigin); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOriginHash); + const nsLiteralCString doubleclick("doubleclick.net"); + const nsLiteralCString doubleclickHash( + "uXNT1PzjAVau8b402OMAIGDejKbiXfQX5iXvPASfO/s="); + const nsLiteralCString telemetryTest1("telemetry.test_test1"); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclickHash); + + // Properly prepare the prio prefs + // (Sourced from PrioEncoder.cpp from when it was being prototyped) + const nsLiteralCString prioKeyA( + "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); + const nsLiteralCString prioKeyB( + "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); Preferences::SetCString("prio.publicKeyA", prioKeyA); Preferences::SetCString("prio.publicKeyB", prioKeyB); nsTArray> encodedStrings; - GetEncodedOriginStrings( - aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), encodedStrings); + GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), + encodedStrings); ASSERT_EQ(2 * TelemetryOrigin::SizeOfPrioDatasPerMetric(), encodedStrings.Length()); @@ -143,14 +133,12 @@ TEST_F(TelemetryTestFixture, RecordOriginTwiceMixed) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE( - JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) + ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); JS::RootedValue count(aCx); - ASSERT_TRUE( - JS_GetProperty(aCx, originsObj, kDoubleclickOrigin.get(), &count)); + ASSERT_TRUE(JS_GetProperty(aCx, originsObj, doubleclick.get(), &count)); ASSERT_TRUE(count.isInt32() && count.toInt32() == 2) << "Must have recorded the origin exactly twice."; } @@ -161,7 +149,11 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { Unused << mTelemetry->ClearOrigins(); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin1); + const nsLiteralCString telemetryTest1("telemetry.test_test1"); + const nsLiteralCString unknown("this origin isn't known to Origin Telemetry"); + const nsLiteralCString unknown2("neither is this one"); + + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown); JS::RootedValue originSnapshot(aCx); GetOriginSnapshot(aCx, &originSnapshot); @@ -171,8 +163,7 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { JS::RootedValue origins(aCx); JS::RootedObject snapshotObj(aCx, &originSnapshot.toObject()); - ASSERT_TRUE( - JS_GetProperty(aCx, snapshotObj, kTelemetryTest1Metric.get(), &origins)) + ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj, telemetryTest1.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj(aCx, &origins.toObject()); @@ -182,7 +173,7 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { << "Must have recorded the unknown origin exactly once."; // Record a second, different unknown origin and ensure only one is stored. - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin2); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown2); GetOriginSnapshot(aCx, &originSnapshot); @@ -190,8 +181,7 @@ TEST_F(TelemetryTestFixture, RecordUnknownOrigin) { << "Origin snapshot must not be null/undefined."; JS::RootedObject snapshotObj2(aCx, &originSnapshot.toObject()); - ASSERT_TRUE( - JS_GetProperty(aCx, snapshotObj2, kTelemetryTest1Metric.get(), &origins)) + ASSERT_TRUE(JS_GetProperty(aCx, snapshotObj2, telemetryTest1.get(), &origins)) << "telemetry.test_test1 must be in the snapshot."; JS::RootedObject originsObj2(aCx, &origins.toObject()); @@ -207,21 +197,30 @@ TEST_F(TelemetryTestFixture, EncodedSnapshot) { Unused << mTelemetry->ClearOrigins(); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOrigin); - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, kUnknownOrigin1); + const nsLiteralCString doubleclick("doubleclick.net"); + const nsLiteralCString unknown("this origin isn't known to Origin Telemetry"); + const nsLiteralCString telemetryTest1("telemetry.test_test1"); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, unknown); + + // Properly prepare the prio prefs + // (Sourced from PrioEncoder.cpp from when it was being prototyped) + const nsLiteralCString prioKeyA( + "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733"); + const nsLiteralCString prioKeyB( + "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50"); Preferences::SetCString("prio.publicKeyA", prioKeyA); Preferences::SetCString("prio.publicKeyB", prioKeyB); nsTArray> firstStrings; - GetEncodedOriginStrings( - aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), firstStrings); + GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), + firstStrings); // Now snapshot a second time and ensure the encoded payloads change. nsTArray> secondStrings; - GetEncodedOriginStrings( - aCx, kTelemetryTest1Metric + NS_LITERAL_CSTRING("-%u"), secondStrings); + GetEncodedOriginStrings(aCx, telemetryTest1 + NS_LITERAL_CSTRING("-%u"), + secondStrings); const auto sizeOfPrioDatasPerMetric = TelemetryOrigin::SizeOfPrioDatasPerMetric(); @@ -266,6 +265,8 @@ TEST_F(TelemetryTestFixture, OriginTelemetryNotifiesTopic) { Unused << mTelemetry->ClearOrigins(); const char* kTopic = "origin-telemetry-storage-limit-reached"; + NS_NAMED_LITERAL_CSTRING(doubleclick, "doubleclick.net"); + NS_NAMED_LITERAL_CSTRING(fb, "fb.com"); MockObserver* mo = new MockObserver(); nsCOMPtr nsMo(mo); @@ -279,11 +280,9 @@ TEST_F(TelemetryTestFixture, OriginTelemetryNotifiesTopic) { for (size_t i = 0; i < size; ++i) { if (i < size - 1) { // Let's ensure we only notify the once. - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kFacebookOrigin); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, fb); } - Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, - kDoubleclickOrigin); + Telemetry::RecordOrigin(OriginMetricID::TelemetryTest_Test1, doubleclick); } os->RemoveObserver(nsMo, kTopic); From f20a8dc5633ef4df93d45b8495f7e29d519f19fe Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Mon, 20 May 2019 12:33:06 +0000 Subject: [PATCH 010/129] Bug 1541355 - Don't display DevTools internal frames in Netmonitor stacktrace. r=Honza. Before sending back the stacktrace, we remove all the devtools internal frames using removeFramesAboveDebuggerEval. A test (that was failing without the fix) is added to ensure this works as expected. The test revealed some issues in webconsole-connection-proxy (mostly trying to access webConsoleUI while closing the toolbox), which we fix in the patch as well. Differential Revision: https://phabricator.services.mozilla.com/D31249 --HG-- extra : moz-landing-system : lando --- .../client/shared/components/StackTrace.js | 4 ++ .../webconsole/test/mochitest/browser.ini | 1 + ...es_stacktrace_console_initiated_request.js | 63 +++++++++++++++++++ .../webconsole/webconsole-connection-proxy.js | 9 +++ .../network-monitor/stack-trace-collector.js | 4 +- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_stacktrace_console_initiated_request.js diff --git a/devtools/client/shared/components/StackTrace.js b/devtools/client/shared/components/StackTrace.js index be63c69c4857..620372f677cf 100644 --- a/devtools/client/shared/components/StackTrace.js +++ b/devtools/client/shared/components/StackTrace.js @@ -48,6 +48,10 @@ class StackTrace extends Component { sourceMapService, } = this.props; + if (!stacktrace) { + return null; + } + const frames = []; stacktrace.forEach((s, i) => { if (s.asyncCause) { diff --git a/devtools/client/webconsole/test/mochitest/browser.ini b/devtools/client/webconsole/test/mochitest/browser.ini index 2f9ff7349575..ef449592670f 100644 --- a/devtools/client/webconsole/test/mochitest/browser.ini +++ b/devtools/client/webconsole/test/mochitest/browser.ini @@ -341,6 +341,7 @@ skip-if = true # Bug 1438979 [browser_webconsole_network_message_ctrl_click.js] [browser_webconsole_network_messages_openinnet.js] [browser_webconsole_network_messages_resend_request.js] +[browser_webconsole_network_messages_stacktrace_console_initiated_request.js] [browser_webconsole_network_messages_status_code.js] [browser_webconsole_network_requests_from_chrome.js] [browser_webconsole_network_reset_filter.js] diff --git a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_stacktrace_console_initiated_request.js b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_stacktrace_console_initiated_request.js new file mode 100644 index 000000000000..ec01a6f2b5d7 --- /dev/null +++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_stacktrace_console_initiated_request.js @@ -0,0 +1,63 @@ + +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_FILE = "test-network-request.html"; +const TEST_PATH = "https://example.com/browser/devtools/client/webconsole/" + + "test/mochitest/"; +const TEST_URI = TEST_PATH + TEST_FILE; + +pushPref("devtools.webconsole.filter.netxhr", true); + +add_task(async function task() { + const hud = await openNewTabAndConsole(TEST_URI); + + const xhrUrl = TEST_PATH + "sjs_slow-response-test-server.sjs"; + const onRequestUpdates = waitForRequestUpdates(hud); + const onPayloadReady = waitForPayloadReady(hud); + + info("Fire an XHR POST request from the console."); + const { node: messageNode } = await executeAndWaitForMessage(hud, ` + xhrConsole = () => testXhrPostSlowResponse(); + xhrConsole(); + `, xhrUrl); + + ok(messageNode, "Network message found."); + + await onRequestUpdates; + + info("Expand the network message"); + await expandXhrMessage(messageNode); + + await onPayloadReady; + + const stackTraceTab = messageNode.querySelector("#stack-trace-tab"); + ok(stackTraceTab, "StackTrace tab is available"); + + stackTraceTab.click(); + const selector = "#stack-trace-panel .frame-link"; + await waitFor(() => messageNode.querySelector(selector)); + const frames = [...messageNode.querySelectorAll(selector)]; + + is(frames.length, 4, "There's the expected frames"); + const functionNames = frames.map(f => + f.querySelector(".frame-link-function-display-name").textContent); + is(functionNames.join("|"), "makeXhr|testXhrPostSlowResponse|xhrConsole|", + "The stacktrace does not have devtools' internal frames"); +}); + +async function waitForPayloadReady(hud) { + return hud.ui.once("network-request-payload-ready"); +} + +async function waitForRequestUpdates(hud) { + return hud.ui.once("network-message-updated"); +} + +function expandXhrMessage(node) { + info("Click on XHR message and wait for the network detail panel to be displayed"); + node.querySelector(".url").click(); + return waitFor(() => node.querySelector(".network-info")); +} diff --git a/devtools/client/webconsole/webconsole-connection-proxy.js b/devtools/client/webconsole/webconsole-connection-proxy.js index 5d95c5d50a6d..1367a26dfb99 100644 --- a/devtools/client/webconsole/webconsole-connection-proxy.js +++ b/devtools/client/webconsole/webconsole-connection-proxy.js @@ -219,10 +219,19 @@ WebConsoleConnectionProxy.prototype = { * Dispatch a message event on the new frontend and emit an event for tests. */ dispatchMessageUpdate: function(networkInfo, response) { + // Some message might try to update while we are closing the toolbox. + if (!this.webConsoleUI) { + return; + } this.webConsoleUI.wrapper.dispatchMessageUpdate(networkInfo, response); }, dispatchRequestUpdate: function(id, data) { + // Some request might try to update while we are closing the toolbox. + if (!this.webConsoleUI) { + return; + } + this.webConsoleUI.wrapper.dispatchRequestUpdate(id, data); }, diff --git a/devtools/server/actors/network-monitor/stack-trace-collector.js b/devtools/server/actors/network-monitor/stack-trace-collector.js index 38c78e9efff6..aee4f2f8ef80 100644 --- a/devtools/server/actors/network-monitor/stack-trace-collector.js +++ b/devtools/server/actors/network-monitor/stack-trace-collector.js @@ -15,6 +15,8 @@ loader.lazyRequireGetter(this, "ChannelEventSinkFactory", loader.lazyRequireGetter(this, "matchRequest", "devtools/server/actors/network-monitor/network-observer", true); +loader.lazyRequireGetter(this, "WebConsoleUtils", + "devtools/server/actors/webconsole/utils", true); function StackTraceCollector(filters, netmonitors) { this.filters = filters; @@ -156,7 +158,7 @@ StackTraceCollector.prototype = { getStackTrace(channelId) { const trace = this.stacktracesById.get(channelId); this.stacktracesById.delete(channelId); - return trace; + return WebConsoleUtils.removeFramesAboveDebuggerEval(trace); }, onGetStack(msg) { From 0b10e77ba6c84ca66d005f20160028977a4745bf Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 20 May 2019 14:40:10 +0000 Subject: [PATCH 011/129] Bug 1550001 - Provide event listener breakpoint UI r=loganfsmyth Differential Revision: https://phabricator.services.mozilla.com/D30986 --HG-- extra : moz-landing-system : lando --- .../debugger/src/actions/event-listeners.js | 93 ++++- .../debugger/src/actions/types/index.js | 27 +- .../client/debugger/src/client/firefox.js | 3 + .../debugger/src/client/firefox/commands.js | 17 +- .../debugger/src/client/firefox/types.js | 7 +- devtools/client/debugger/src/client/index.js | 8 +- .../SecondaryPanes/EventListeners.js | 142 ++++---- .../tests/EventListeners.spec.js | 82 +++++ .../__snapshots__/EventListeners.spec.js.snap | 320 ++++++++++++++++++ .../debugger/src/reducers/event-listeners.js | 68 ++-- .../client/debugger/src/reducers/types.js | 2 + devtools/client/debugger/src/utils/prefs.js | 5 +- devtools/client/preferences/debugger.js | 4 +- 13 files changed, 648 insertions(+), 130 deletions(-) create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/EventListeners.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/EventListeners.spec.js.snap diff --git a/devtools/client/debugger/src/actions/event-listeners.js b/devtools/client/debugger/src/actions/event-listeners.js index 0e47899bf087..4e1e41e321f7 100644 --- a/devtools/client/debugger/src/actions/event-listeners.js +++ b/devtools/client/debugger/src/actions/event-listeners.js @@ -4,29 +4,88 @@ // @flow +import { uniq, remove } from "lodash"; + import { asyncStore } from "../utils/prefs"; +import { + getActiveEventListeners, + getEventListenerExpanded, +} from "../selectors"; + import type { ThunkArgs } from "./types"; -import type { EventListenerBreakpoints } from "../types"; -export function addEventListeners(events: EventListenerBreakpoints) { - return async ({ dispatch, client }: ThunkArgs) => { - await dispatch({ - type: "ADD_EVENT_LISTENERS", - events, - }); - const newList = await asyncStore.eventListenerBreakpoints; - client.setEventListenerBreakpoints(newList); +async function updateBreakpoints(dispatch, client, newEvents: string[]) { + dispatch({ type: "UPDATE_EVENT_LISTENERS", active: newEvents }); + + const current = await asyncStore.eventListenerBreakpoints; + asyncStore.eventListenerBreakpoints = { + ...current, + active: newEvents, + }; + + client.setEventListenerBreakpoints(newEvents); +} + +async function updateExpanded(dispatch, newExpanded: string[]) { + dispatch({ + type: "UPDATE_EVENT_LISTENER_EXPANDED", + expanded: newExpanded, + }); + + const current = await asyncStore.eventListenerBreakpoints; + asyncStore.eventListenerBreakpoints = { + ...current, + expanded: newExpanded, }; } -export function removeEventListeners(events: EventListenerBreakpoints) { - return async ({ dispatch, client }: ThunkArgs) => { - await dispatch({ - type: "REMOVE_EVENT_LISTENERS", - events, - }); - const newList = await asyncStore.eventListenerBreakpoints; - client.setEventListenerBreakpoints(newList); +export function addEventListenerBreakpoints(eventsToAdd: string[]) { + return async ({ dispatch, client, getState }: ThunkArgs) => { + const activeListenerBreakpoints = await getActiveEventListeners(getState()); + + const newEvents = uniq([...eventsToAdd, ...activeListenerBreakpoints]); + + updateBreakpoints(dispatch, client, newEvents); + }; +} + +export function removeEventListenerBreakpoints(eventsToRemove: string[]) { + return async ({ dispatch, client, getState }: ThunkArgs) => { + const activeListenerBreakpoints = await getActiveEventListeners(getState()); + + const newEvents = remove( + activeListenerBreakpoints, + event => !eventsToRemove.includes(event) + ); + + updateBreakpoints(dispatch, client, newEvents); + }; +} + +export function addEventListenerExpanded(category: string) { + return async ({ dispatch, getState }: ThunkArgs) => { + const expanded = await getEventListenerExpanded(getState()); + + const newExpanded = uniq([...expanded, category]); + + await updateExpanded(dispatch, newExpanded); + }; +} + +export function removeEventListenerExpanded(category: string) { + return async ({ dispatch, getState }: ThunkArgs) => { + const expanded = await getEventListenerExpanded(getState()); + + const newExpanded = expanded.filter(expand => expand != category); + + updateExpanded(dispatch, newExpanded); + }; +} + +export function getEventListenerBreakpointTypes() { + return async ({ dispatch, client }: ThunkArgs) => { + const categories = await client.getEventListenerBreakpointTypes(); + dispatch({ type: "RECEIVE_EVENT_LISTENER_TYPES", categories }); }; } diff --git a/devtools/client/debugger/src/actions/types/index.js b/devtools/client/debugger/src/actions/types/index.js index 51a110cf42c6..01296b64b8e7 100644 --- a/devtools/client/debugger/src/actions/types/index.js +++ b/devtools/client/debugger/src/actions/types/index.js @@ -159,6 +159,30 @@ export type { export type { panelPositionType } from "./UIAction"; +export type { ASTAction } from "./ASTAction"; + +type ActiveEventListener = string; +type EventListenerEvent = { name: string, id: ActiveEventListener }; +type EventListenerCategory = { name: string, events: EventListenerEvent[] }; + +export type EventListenerActiveList = ActiveEventListener[]; +export type EventListenerCategoryList = EventListenerCategory[]; +export type EventListenerExpandedList = string[]; + +export type EventListenerAction = + | {| + +type: "UPDATE_EVENT_LISTENERS", + +active: EventListenerActiveList, + |} + | {| + +type: "RECEIVE_EVENT_LISTENER_TYPES", + +categories: EventListenerCategoryList, + |} + | {| + +type: "UPDATE_EVENT_LISTENER_EXPANDED", + +expanded: EventListenerExpandedList, + |}; + /** * Actions: Source, Breakpoint, and Navigation * @@ -180,4 +204,5 @@ export type Action = | FileTextSearchAction | ProjectTextSearchAction | DebuggeeAction - | SourceTreeAction; + | SourceTreeAction + | EventListenerAction; diff --git a/devtools/client/debugger/src/client/firefox.js b/devtools/client/debugger/src/client/firefox.js index 3d8fb32624cb..e24f96eb7bee 100644 --- a/devtools/client/debugger/src/client/firefox.js +++ b/devtools/client/debugger/src/client/firefox.js @@ -47,6 +47,9 @@ export async function onConnect(connection: any, actions: Object) { skipBreakpoints: prefs.skipPausing, }); + // Retrieve possible event listener breakpoints + actions.getEventListenerBreakpointTypes(); + // In Firefox, we need to initially request all of the sources. This // usually fires off individual `newSource` notifications as the // debugger finds them, but there may be existing sources already in diff --git a/devtools/client/debugger/src/client/firefox/commands.js b/devtools/client/debugger/src/client/firefox/commands.js index 59758b83ee75..b7cf035a7f43 100644 --- a/devtools/client/debugger/src/client/firefox/commands.js +++ b/devtools/client/debugger/src/client/firefox/commands.js @@ -16,7 +16,6 @@ import type { BreakpointLocation, BreakpointOptions, PendingLocation, - EventListenerBreakpoints, Frame, FrameId, GeneratedSourceData, @@ -36,6 +35,8 @@ import type { SourcesPacket, } from "./types"; +import type { EventListenerCategoryList } from "../../actions/types"; + let workerClients: Object; let threadClient: ThreadClient; let tabTarget: TabTarget; @@ -361,8 +362,17 @@ function interrupt(thread: string): Promise<*> { return lookupThreadClient(thread).interrupt(); } -function setEventListenerBreakpoints(eventTypes: EventListenerBreakpoints) { - // TODO: Figure out what sendpoint we want to hit +async function setEventListenerBreakpoints(ids: string[]) { + await threadClient.setActiveEventBreakpoints(ids); + await forEachWorkerThread(thread => thread.setActiveEventBreakpoints(ids)); +} + +// eslint-disable-next-line +async function getEventListenerBreakpointTypes(): Promise< + EventListenerCategoryList +> { + const { value } = await threadClient.getAvailableEventBreakpoints(); + return value; } function pauseGrip(thread: string, func: Function): ObjectClient { @@ -525,6 +535,7 @@ const clientCommands = { sendPacket, setSkipPausing, setEventListenerBreakpoints, + getEventListenerBreakpointTypes, waitForWorkers, detachWorkers, hasWasmSupport, diff --git a/devtools/client/debugger/src/client/firefox/types.js b/devtools/client/debugger/src/client/firefox/types.js index 8f87962d777c..3c89c5041aec 100644 --- a/devtools/client/debugger/src/client/firefox/types.js +++ b/devtools/client/debugger/src/client/firefox/types.js @@ -25,6 +25,8 @@ import type { Range, } from "../../types"; +import type { EventListenerCategoryList } from "../../actions/types"; + type URL = string; /** @@ -369,7 +371,10 @@ export type ThreadClient = { actor: ActorId, request: (payload: Object) => Promise<*>, url: string, - setEventListenerBreakpoints: (string[]) => void, + setActiveEventBreakpoints: (string[]) => void, + getAvailableEventBreakpoints: () => Promise<{| + value: EventListenerCategoryList, + |}>, skipBreakpoints: boolean => Promise<{| skip: boolean |}>, }; diff --git a/devtools/client/debugger/src/client/index.js b/devtools/client/debugger/src/client/index.js index e68801c9ec6f..e4fe19c14671 100644 --- a/devtools/client/debugger/src/client/index.js +++ b/devtools/client/debugger/src/client/index.js @@ -15,6 +15,7 @@ import { bootstrapStore, bootstrapWorkers, } from "../utils/bootstrap"; + import { initialBreakpointsState } from "../reducers/breakpoints"; import type { Panel } from "./firefox/types"; @@ -47,7 +48,12 @@ async function loadInitialState() { const breakpoints = initialBreakpointsState(xhrBreakpoints); - return { pendingBreakpoints, tabs, breakpoints, eventListenerBreakpoints }; + return { + pendingBreakpoints, + tabs, + breakpoints, + eventListenerBreakpoints, + }; } function getClient(connection: any) { diff --git a/devtools/client/debugger/src/components/SecondaryPanes/EventListeners.js b/devtools/client/debugger/src/components/SecondaryPanes/EventListeners.js index be2ce126448f..ad18d6c0a01d 100644 --- a/devtools/client/debugger/src/components/SecondaryPanes/EventListeners.js +++ b/devtools/client/debugger/src/components/SecondaryPanes/EventListeners.js @@ -9,141 +9,121 @@ import classnames from "classnames"; import { connect } from "../../utils/connect"; import actions from "../../actions"; -import { getActiveEventListeners } from "../../selectors"; +import { + getActiveEventListeners, + getEventListenerBreakpointTypes, + getEventListenerExpanded, +} from "../../selectors"; import AccessibleImage from "../shared/AccessibleImage"; -import type { EventListenerBreakpoints } from "../../types"; +import type { + EventListenerActiveList, + EventListenerCategoryList, + EventListenerExpandedList, +} from "../../actions/types"; import "./EventListeners.css"; -const CATEGORIES = { - Mouse: ["click", "mouseover", "dblclick"], - Keyboard: ["keyup", "keydown"], -}; - type Props = { - addEventListeners: typeof actions.addEventListeners, - removeEventListeners: typeof actions.removeEventListeners, - activeEventListeners: EventListenerBreakpoints, + categories: EventListenerCategoryList, + expandedCategories: EventListenerExpandedList, + activeEventListeners: EventListenerActiveList, + addEventListeners: typeof actions.addEventListenerBreakpoints, + removeEventListeners: typeof actions.removeEventListenerBreakpoints, + addEventListenerExpanded: typeof actions.addEventListenerExpanded, + removeEventListenerExpanded: typeof actions.removeEventListenerExpanded, }; -type State = { - expandedCategories: string[], -}; - -function getKey(category: string, eventType: string) { - return `${category}:${eventType}`; -} - -class EventListeners extends Component { - constructor(props) { - super(props); - - this.state = { - expandedCategories: [], - }; - } - - onCategoryToggle(category, event) { - const { expandedCategories } = this.state; +class EventListeners extends Component { + onCategoryToggle(category) { + const { + expandedCategories, + removeEventListenerExpanded, + addEventListenerExpanded, + } = this.props; if (expandedCategories.includes(category)) { - this.setState({ - expandedCategories: expandedCategories.filter( - eventCategory => eventCategory !== category - ), - }); + removeEventListenerExpanded(category); } else { - this.setState({ - expandedCategories: [...expandedCategories, category], - }); + addEventListenerExpanded(category); } } onCategoryClick(category, isChecked) { const { addEventListeners, removeEventListeners } = this.props; - const events = CATEGORIES[category].map(eventType => - getKey(category, eventType) - ); + const eventsIds = category.events.map(event => event.id); if (isChecked) { - addEventListeners(events); + addEventListeners(eventsIds); } else { - removeEventListeners(events); + removeEventListeners(eventsIds); } } - onEventTypeClick(eventType, isChecked) { + onEventTypeClick(eventId, isChecked) { const { addEventListeners, removeEventListeners } = this.props; if (isChecked) { - addEventListeners([eventType]); + addEventListeners([eventId]); } else { - removeEventListeners([eventType]); + removeEventListeners([eventId]); } } renderCategoryHeading(category) { - const { expandedCategories } = this.state; - const { activeEventListeners } = this.props; + const { activeEventListeners, expandedCategories } = this.props; + const { events } = category; - const eventTypes = CATEGORIES[category]; - - const expanded = expandedCategories.includes(category); - const checked = eventTypes.every(eventType => - activeEventListeners.includes(getKey(category, eventType)) - ); + const expanded = expandedCategories.includes(category.name); + const checked = events.every(({ id }) => activeEventListeners.includes(id)); const indeterminate = - !checked && - eventTypes.some(eventType => - activeEventListeners.includes(getKey(category, eventType)) - ); + !checked && events.some(({ id }) => activeEventListeners.includes(id)); return (
); } renderCategoryListing(category) { - const { activeEventListeners } = this.props; - const { expandedCategories } = this.state; + const { activeEventListeners, expandedCategories } = this.props; - const expanded = expandedCategories.includes(category); + const expanded = expandedCategories.includes(category.name); if (!expanded) { return null; } return (