From 40e78ce65d19e830d0eb2b46bf2c6f097ef9c93b Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Sat, 9 May 2020 00:02:39 -0700 Subject: [PATCH 01/33] improve treedump capabilities --- packages/E2ETest/windows/ReactUWPTestApp.sln | 1 + .../TreeDumpControlViewManager.cs | 170 +------------ .../windows/TreeDumpLibrary/TreeDumpHelper.cs | 238 ++++++++++++++++++ .../TreeDumpLibrary/TreeDumpLibrary.csproj | 4 +- .../TreeDumpLibrary/VisualTreeDumper.cs | 99 +++++++- 5 files changed, 333 insertions(+), 179 deletions(-) create mode 100644 packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs diff --git a/packages/E2ETest/windows/ReactUWPTestApp.sln b/packages/E2ETest/windows/ReactUWPTestApp.sln index fd7c8a089aa..d632b950855 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp.sln +++ b/packages/E2ETest/windows/ReactUWPTestApp.sln @@ -43,6 +43,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ReactNative.Manag EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\..\vnext\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4 ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4 ..\..\..\vnext\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4 ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4 diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs index 1e12a33264b..fea206cd49f 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs @@ -5,11 +5,8 @@ using Microsoft.ReactNative.Managed; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Threading.Tasks; using Windows.ApplicationModel.DataTransfer; -using Windows.Data.Json; using Windows.Storage; using Windows.UI.ViewManagement; using Windows.UI.Xaml; @@ -126,180 +123,25 @@ private async void dispatcherTimer_Tick(object sender, object e) m_timer.Stop(); if (VisualTreeHelper.GetParent(m_textBlock) != null) { - await MatchTreeDumpFromLayoutUpdateAsync(); - } - } - private DependencyObject FindChildWithMatchingUIAID(DependencyObject element) - { - string automationId = (string)element.GetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty); - if (automationId == m_uiaID) - { - return element; - } - int childrenCount = VisualTreeHelper.GetChildrenCount(element); - for (int i = 0; i < childrenCount; i++) - { - var result = FindChildWithMatchingUIAID(VisualTreeHelper.GetChild(element, i)); - if (result != null) - { - return result; - } - } - - return null; - } - - private async Task MatchTreeDumpFromLayoutUpdateAsync() - { - // First find root - DependencyObject current = m_textBlock; - DependencyObject parent = VisualTreeHelper.GetParent(current); - while (parent != null) - { - current = parent; - parent = VisualTreeHelper.GetParent(current); - } - - DependencyObject dumpRoot = current; - // if UIAID is passed in from test, find the matching child as the root to dump - if (m_uiaID != null) - { - var matchingNode = FindChildWithMatchingUIAID(current); - if (matchingNode != null) + var matchSuccessful = await TreeDumpHelper.MatchTreeDumpFromLayoutUpdateAsync(m_dumpID, m_uiaID, m_textBlock, m_additionalProperties, DumpTreeMode.Json, m_dumpExpectedText); + if (!matchSuccessful) { - dumpRoot = matchingNode; - } - } - - string dumpText = VisualTreeDumper.DumpTree(dumpRoot, m_textBlock /* exclude */ , m_additionalProperties, mode); - if (dumpText != m_dumpExpectedText) - { - await MatchDump(dumpText); - } - } - - private readonly DumpTreeMode mode = DumpTreeMode.Json; - - private async Task MatchDump(string dumpText) - { - StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{GetMasterFile()}"); - if (m_dumpExpectedText == null) - { - try - { - m_dumpExpectedText = await FileIO.ReadTextAsync(masterFile); - StorageFolder storageFolder = ApplicationData.Current.LocalFolder; - string copyFileName = GetMasterFile(); - var copyDumpFile = await storageFolder.CreateFileAsync(copyFileName, CreationCollisionOption.ReplaceExisting); - await FileIO.WriteTextAsync(copyDumpFile, m_dumpExpectedText); - } - catch (IOException) - { - UpdateResult(false /*matchDump*/ , "Tree dump master file not found in testapp package!"); - } - } + StorageFile outFile = await storageFolder.GetFileAsync(TreeDumpHelper.GetOutputFile(m_dumpID)); + StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{TreeDumpHelper.GetMasterFile(m_dumpID)}"); - if (!DumpsAreEqual(m_dumpExpectedText, dumpText)) - { - StorageFolder storageFolder = ApplicationData.Current.LocalFolder; - string fileName = GetOutputFile(); - try - { - StorageFile outFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); - await FileIO.WriteTextAsync(outFile, dumpText); UpdateResult(false /*matchDump*/ , $"Tree dump file does not match master at {masterFile.Path} - See output at {outFile.Path}", GetInlines(masterFile, outFile, m_textBlock)); } - catch (IOException) + else { - UpdateResult(false /*matchDump*/ , "Can't write dump output file:" + fileName); + UpdateResult(true /*matchDump*/ , ""); } - } - else - { - UpdateResult(true /*matchDump*/ , ""); - } - } - - private bool DumpsAreEqual(string dumpExpectedText, string dumpText) - { - if (mode == DumpTreeMode.Default) - { - return dumpExpectedText == dumpText; - } - else - { - JsonValue expected = JsonValue.Parse(dumpExpectedText); - JsonValue actual = JsonValue.Parse(dumpText); - return JsonComparesEqual(expected, actual); - } - } - private bool JsonComparesEqual(IJsonValue expected, IJsonValue actual) - { - if (expected.ValueType != actual.ValueType) - { - return false; - } - switch (expected.ValueType) - { - case JsonValueType.String: - if (expected.GetString() == actual.GetString()) - { - return true; - } - else { Debug.WriteLine($"Expected {expected.GetString()} got {actual.GetString()}"); return false; } - case JsonValueType.Number: - return expected.GetNumber() == actual.GetNumber(); - case JsonValueType.Boolean: - return expected.GetBoolean() == actual.GetBoolean(); - case JsonValueType.Null: - return true; - case JsonValueType.Array: - { - var ea = expected.GetArray(); - var aa = actual.GetArray(); - if (ea.Count != aa.Count) { return false; } - for (uint i = 0; i < ea.Count; i++) - { - if (!JsonComparesEqual(ea[(int)i], aa[(int)i])) - { - return false; - } - } - return true; - } - case JsonValueType.Object: - { - var eo = expected.GetObject(); - var ao = actual.GetObject(); - if (eo.Keys.Count != ao.Keys.Count) { return false; } - foreach (var key in eo.Keys) - { - if (!JsonComparesEqual(eo.GetNamedValue(key), ao.GetNamedValue(key))) - { - return false; - } - } - return true; - } - default: - throw new ArgumentException(); } } - private string GetOutputFile() - { - return "TreeDump\\" + m_dumpID + (mode == DumpTreeMode.Json ? ".json" : ".out"); - } - - private string GetMasterFile() - { - return "TreeDump\\masters\\" + m_dumpID + (mode == DumpTreeMode.Json ? ".json" : ".txt"); - } - private static IList GetInlines(StorageFile masterFile, StorageFile outFile, UIElement anchor) { Hyperlink masterLink = new Hyperlink(); diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs new file mode 100644 index 00000000000..55daeb7c57f --- /dev/null +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs @@ -0,0 +1,238 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Windows.Data.Json; +using Windows.Storage; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +namespace TreeDumpLibrary +{ + public static class TreeDumpHelper + { + + private static DependencyObject FindChildWithMatchingUIAID(DependencyObject element, string uiaId) + { + string automationId = (string)element.GetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty); + if (automationId == uiaId) + { + return element; + } + int childrenCount = VisualTreeHelper.GetChildrenCount(element); + for (int i = 0; i < childrenCount; i++) + { + var result = FindChildWithMatchingUIAID(VisualTreeHelper.GetChild(element, i), uiaId); + if (result != null) + { + return result; + } + } + + return null; + } + + internal static async Task MatchTreeDumpFromLayoutUpdateAsync(string dumpID, string uiaId, TextBlock textBlock, IList additionalProperties, DumpTreeMode mode, string dumpExpectedText) + { + // First find root + DependencyObject current = textBlock; + DependencyObject parent = VisualTreeHelper.GetParent(current); + while (parent != null) + { + current = parent; + parent = VisualTreeHelper.GetParent(current); + } + + DependencyObject dumpRoot = current; + // if UIAID is passed in from test, find the matching child as the root to dump + if (uiaId != null) + { + var matchingNode = FindChildWithMatchingUIAID(current, uiaId); + if (matchingNode != null) + { + dumpRoot = matchingNode; + } + } + + string dumpText = VisualTreeDumper.DumpTree(dumpRoot, textBlock /* exclude */, additionalProperties, mode); + if (dumpText != dumpExpectedText) + { + return await MatchDump(dumpText, dumpID); + } + return true; + } + + + internal static async Task MatchDump(string outputJson, string dumpID) + { + Debug.WriteLine($"master file = {Windows.ApplicationModel.Package.Current.InstalledLocation.Path}\\Assets\\{GetMasterFile(dumpID)}"); + StorageFolder storageFolder = ApplicationData.Current.LocalFolder; + string fileName = GetOutputFile(dumpID); + Debug.WriteLine($"output file = {storageFolder.Path + "\\" + fileName}"); + + StorageFile outFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); + await FileIO.WriteTextAsync(outFile, outputJson); + + StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{GetMasterFile(dumpID)}"); + + string masterJson = await FileIO.ReadTextAsync(masterFile); + + if (!DumpsAreEqual(masterJson, outputJson)) + { + return false; + } + else + { + return true; + } + } + + public static bool DumpsAreEqual(string dumpExpectedText, string dumpText) + { + JsonValue expected = JsonValue.Parse(dumpExpectedText); + JsonValue actual = JsonValue.Parse(dumpText); + return JsonComparesEqual(expected, actual, "root"); + } + + static readonly double epsilon = 1.0; + + private static bool JsonComparesEqual(IJsonValue expected, IJsonValue actual, string keyName) + { + //const string anything = "‎"; + const string Anything = ""; + //System.Diagnostics.Debug.Assert(anything == Anything); + if (expected.ValueType == JsonValueType.String && Regex.Replace(expected.GetString(), @"\p{C}", "") == Anything) + { + Debug.WriteLine($"Skipping ignored value: {actual.ValueType} {actual}"); + return true; + } + //Debug.WriteLine($"keyname: {keyName} {expected.ValueType} {actual.ValueType}"); + if (expected.ValueType != actual.ValueType) + { + Debug.WriteLine($"Expected {expected} got {actual}"); + return false; + } + switch (expected.ValueType) + { + case JsonValueType.String: + if (expected.GetString() != actual.GetString()) + { + Debug.WriteLine($"string:Expected {expected.GetString()} got {actual.GetString()}"); + return false; + } + return true; + case JsonValueType.Number: + if (Math.Abs(expected.GetNumber() - actual.GetNumber()) > epsilon) + { + Debug.WriteLine($"number: {keyName} {expected.GetNumber()} {actual.GetNumber()}"); + return false; + } + return true; + case JsonValueType.Boolean: + return expected.GetBoolean() == actual.GetBoolean(); + case JsonValueType.Null: + return true; + case JsonValueType.Array: + { + var ea = expected.GetArray(); + var aa = actual.GetArray(); + if (!JsonCompareArray(ea, aa)) + { + Debug.WriteLine("in key " + keyName); + return false; + } + return true; + } + case JsonValueType.Object: + { + if (!JsonCompareObject(expected.GetObject(), actual.GetObject())) + { + Debug.WriteLine("in key " + keyName); + return false; + } + return true; + } + default: + throw new ArgumentException(); + } + } + + private static bool JsonCompareArray(JsonArray ea, JsonArray aa) + { + if (ea.Count != aa.Count) + { + Debug.WriteLine($"Array count expected {ea.Count} got {aa.Count}"); + return false; + } + for (int i = 0; i < ea.Count; i++) + { + var _e = ea[i]; + var _a = aa[i]; + if (!JsonComparesEqual(_e, _a, "array element")) + { + Debug.WriteLine($"Array element {i} expected {_e.ValueType} got {_a.ValueType}"); + return false; + } + } + return true; + } + + private static bool JsonCompareObject(JsonObject eo, JsonObject ao) + { + var evisible = true; + const string visibilityProperty = "Visibility"; + if (eo.Keys.Contains(visibilityProperty)) + { + evisible = eo[visibilityProperty].GetString() == "Visible"; + eo.Remove("Visibility"); + } + var avisible = true; + if (ao.Keys.Contains(visibilityProperty)) + { + avisible = ao[visibilityProperty].GetString() == "Visible"; + ao.Remove(visibilityProperty); + } + if (avisible != evisible) { return false; } + if (avisible == false) + { + // both are collapsed (or nonexistent) so don't compare children + ao.Remove("children"); + eo.Remove("children"); + } + + if (eo.Keys.Count != ao.Keys.Count) + { + Debug.WriteLine($"Expected {eo.Keys.Count} but got {ao.Keys.Count}"); + Debug.WriteLine(string.Join(", ", eo.Keys)); + Debug.WriteLine(string.Join(", ", ao.Keys)); + return false; + } + foreach (var key in eo.Keys) + { + JsonValue evalue = eo.GetNamedValue(key); + JsonValue avalue = ao.GetNamedValue(key); + if (!JsonComparesEqual(evalue, avalue, key)) + { + Debug.WriteLine($"Property {key} compared differently {evalue.ValueType} {avalue.ValueType}: expected {evalue} got {avalue}"); + return false; + } + } + return true; + } + + public static string GetOutputFile(string dumpID) + { + return "TreeDump\\" + dumpID + ".json"; + } + + public static string GetMasterFile(string dumpID) + { + return "TreeDump\\masters\\" + dumpID + ".json"; + } + } +} diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj index e8ca1d3675b..6d7628538f4 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj @@ -1,6 +1,5 @@  - + Debug @@ -112,6 +111,7 @@ + diff --git a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs index 32a43aa7bd2..69779488887 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs @@ -3,10 +3,15 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Windows.Data.Json; using Windows.Foundation; using Windows.UI.Xaml; +using Windows.UI.Xaml.Automation; using Windows.UI.Xaml.Media; namespace TreeDumpLibrary @@ -51,12 +56,15 @@ public override string ToString() public bool ShouldVisitPropertiesForNode(DependencyObject node) { - return (node as UIElement) != null; + var fe = node as FrameworkElement; + string[] excludedNames = new string[] { "VerticalScrollBar", "HorizontalScrollBar", "ScrollBarSeparator" }; + if (fe != null && excludedNames.Contains(fe.Name)) { return false; } + return true; } - public bool ShouldVisitProperty(PropertyInfo propertyInfo) + public bool ShouldVisitProperty(string propertyName) { - return _filter.ShouldVisitProperty(propertyInfo.Name); + return _filter.ShouldVisitProperty(propertyName); } public void VisitProperty(string propertyName, object value, bool isLast) @@ -88,6 +96,50 @@ public bool ShouldVisitPropertyValue(string propertyName, object value) } } + private static JsonObject FindElementByAutomationId(JsonObject obj, string automationId) + { + if (obj.Keys.Contains("AutomationId") && obj["AutomationId"].GetString() == automationId) + { + return obj; + } + if (obj.Keys.Contains("children")) + { + var array = obj.GetNamedArray("children"); + foreach (var i in array) + { + var element = FindElementByAutomationId(i.GetObject(), automationId); + if (element != null) + { + return element; + } + } + } + return null; + } + + public static IAsyncOperation DoesTreeDumpMatchForRNTester(DependencyObject root) + { + string json = DumpTree(root, null, new string[] { }, DumpTreeMode.Json); + try + { + var obj = JsonValue.Parse(json).GetObject(); + var element = FindElementByAutomationId(obj, "PageHeader"); + if (element == null) + { + return Task.Run(() => false).AsAsyncOperation(); + } + var value = element.GetNamedString("Text"); + var pageName = new Regex(@"[<|>]").Replace(value, ""); + var match = TreeDumpHelper.MatchDump(json, pageName); + return match.AsAsyncOperation(); + } + catch + { + Debug.WriteLine("JSON ERROR:\n" + json); + throw; + } + } + public static string DumpTree(DependencyObject root, DependencyObject excludedNode, IList additionalProperties, DumpTreeMode mode) { var propertyFilter = new DefaultFilter(); @@ -111,20 +163,26 @@ private static void WalkThroughProperties(DependencyObject node, Visitor visitor if (visitor.ShouldVisitPropertiesForNode(node)) { var properties = (from property in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) - where visitor.ShouldVisitProperty(property) && + where visitor.ShouldVisitProperty(property.Name) && visitor.ShouldVisitPropertyValue(property.Name, GetObjectProperty(node, property)) orderby property.Name select property).ToArray(); + var automationId = node.GetValue(AutomationProperties.AutomationIdProperty); for (int i = 0; i < properties.Length; i++) { var property = properties[i]; object value = null; value = GetObjectProperty(node, property); - bool isLast = (i == properties.Length - 1) && !hasChildren; + bool isLast = (i == properties.Length - 1) && !hasChildren && (automationId == null); visitor.VisitProperty(property.Name, value, isLast); } + + if (automationId != null) + { + visitor.VisitProperty("AutomationId", automationId, !hasChildren); + } } } @@ -143,24 +201,36 @@ private static object GetObjectProperty(DependencyObject node, PropertyInfo prop return value; } + private static DependencyObject[] GetChildren(DependencyObject node, Visitor visitor) + { + DependencyObject[] dos = new DependencyObject[VisualTreeHelper.GetChildrenCount(node)]; + for (int i = 0; i < dos.Length; i++) + { + dos[i] = VisualTreeHelper.GetChild(node, i); + } + return dos.Where((n) => visitor.ShouldVisitPropertiesForNode(n)).ToArray(); + } + private static void WalkThroughTree(DependencyObject node, DependencyObject excludedNode, Visitor visitor, bool isLast = true) { - if (node != null) + if (node != null && visitor.ShouldVisitPropertiesForNode(node)) { // Assume that if we have a UIElement, we'll have some properties - visitor.BeginVisitNode(node, node is UIElement); + var children = GetChildren(node, visitor); + bool hasProperties = node is UIElement || (children.Length > 0); + + visitor.BeginVisitNode(node, hasProperties); - var childrenCount = VisualTreeHelper.GetChildrenCount(node); - WalkThroughProperties(node, visitor, childrenCount != 0); - if (childrenCount != 0) + WalkThroughProperties(node, visitor, children.Length != 0); + if (children.Length != 0) { visitor.BeginChildren(); - for (int i = 0; i < childrenCount; i++) + for (int i = 0; i < children.Length; i++) { - var child = VisualTreeHelper.GetChild(node, i); + var child = children[i]; if (child != excludedNode) { - bool isLastChild = (i == childrenCount - 1); + bool isLastChild = (i == children.Length - 1); WalkThroughTree(child, excludedNode, visitor, isLastChild); } } @@ -194,6 +264,7 @@ public DefaultFilter() "Clip", "FlowDirection", "Name", + "Text" /*"ActualOffset" 19h1*/ }; } @@ -258,6 +329,8 @@ public string PropertyValueToString(string propertyName, object propertyObject) public static string Quote(string s) { + s = s.Replace('\t', ' ').Replace("\n", @"\n"); + s = Regex.Replace(s, @"\p{Cs}", ""); // remove surrogate pairs e.g. emojis return '"' + s.Replace("\"", "\\\"") + '"'; } } From 858fdce423bb4a0eac46dd4eca97adb3b6b042e9 Mon Sep 17 00:00:00 2001 From: tudorms <48035227+tudorms@users.noreply.github.com> Date: Sat, 9 May 2020 00:21:56 -0700 Subject: [PATCH 02/33] Reenable V8 for desktop projects (#4840) * Delay load ChakraCore.dll * Change files * clean up unneeded project references * Overwrite property after React.Cpp.props gets included * Change files * change file * Fix WinUI3 * Reverse the conditional logic * Revert some unnecessary changes. Consolidate the preprocessor defines in the props Co-authored-by: tudorm --- ...ve-windows-2020-05-08-14-17-35-master.json | 8 ++ packages/E2ETest/windows/ReactUWPTestApp.sln | 1 + .../playground-win32/Playground-win32.vcxproj | 2 - packages/playground/windows/playground.sln | 1 + .../React.Windows.Desktop.DLL.vcxproj | 18 +-- vnext/Desktop.DLL/packages.config | 1 + ...t.Windows.Desktop.IntegrationTests.vcxproj | 14 -- .../React.Windows.Desktop.UnitTests.vcxproj | 2 - vnext/Desktop/React.Windows.Desktop.vcxproj | 3 +- .../React.Windows.IntegrationTests.vcxproj | 3 - .../JSI.Desktop.UnitTests.vcxproj | 30 +---- vnext/JSI.Desktop.UnitTests/packages.config | 1 + vnext/JSI/Desktop/JSI.Desktop.vcxproj | 6 +- vnext/JSI/Universal/JSI.Universal.vcxproj | 5 - .../Microsoft.ReactNative.vcxproj | 2 - vnext/PropertySheets/React.Cpp.props | 4 +- vnext/ReactUWP/ReactUWP.vcxproj | 2 - vnext/ReactWindows-Desktop.sln | 1 - .../ReactWindowsCore.vcxitems | 12 -- vnext/Shared/Shared.vcxitems | 2 - .../React.Windows.Universal.UnitTests.vcxproj | 3 - vnext/V8Inspector/V8Inspector.vcxproj | 122 ------------------ vnext/V8Inspector/V8Inspector.vcxproj.filters | 63 --------- 23 files changed, 19 insertions(+), 287 deletions(-) create mode 100644 change/react-native-windows-2020-05-08-14-17-35-master.json delete mode 100644 vnext/V8Inspector/V8Inspector.vcxproj delete mode 100644 vnext/V8Inspector/V8Inspector.vcxproj.filters diff --git a/change/react-native-windows-2020-05-08-14-17-35-master.json b/change/react-native-windows-2020-05-08-14-17-35-master.json new file mode 100644 index 00000000000..c55a7882828 --- /dev/null +++ b/change/react-native-windows-2020-05-08-14-17-35-master.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Reenable V8 for desktop projects", + "packageName": "react-native-windows", + "email": "tudorm@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-08T21:17:35.875Z" +} diff --git a/packages/E2ETest/windows/ReactUWPTestApp.sln b/packages/E2ETest/windows/ReactUWPTestApp.sln index fd7c8a089aa..d632b950855 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp.sln +++ b/packages/E2ETest/windows/ReactUWPTestApp.sln @@ -43,6 +43,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ReactNative.Manag EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\..\vnext\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4 ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4 ..\..\..\vnext\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4 ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4 diff --git a/packages/playground/windows/playground-win32/Playground-win32.vcxproj b/packages/playground/windows/playground-win32/Playground-win32.vcxproj index 9e4ec292c29..19af51184fe 100644 --- a/packages/playground/windows/playground-win32/Playground-win32.vcxproj +++ b/packages/playground/windows/playground-win32/Playground-win32.vcxproj @@ -74,8 +74,6 @@ pch.h true Level3 - USE_V8;%(PreprocessorDefinitions) - USE_HERMES;%(PreprocessorDefinitions) shell32.lib;user32.lib;windowsapp.lib;$(ReactNativeWindowsDir)target\$(PlatformTarget)\$(Configuration)\ReactUWP\React.uwp.lib;%(AdditionalDependenices) diff --git a/packages/playground/windows/playground.sln b/packages/playground/windows/playground.sln index 6c610df8452..62a9c082eae 100644 --- a/packages/playground/windows/playground.sln +++ b/packages/playground/windows/playground.sln @@ -43,6 +43,7 @@ EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{0cc28589-39e4-4288-b162-97b959f8b843}*SharedItemsImports = 9 + ..\..\..\vnext\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4 ..\..\..\vnext\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9 ..\..\..\vnext\Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.projitems*{67a1076f-7790-4203-86ea-4402ccb5e782}*SharedItemsImports = 13 ..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{6b6aa847-b32f-41ac-9d3b-48a8cdfa8ade}*SharedItemsImports = 4 diff --git a/vnext/Desktop.DLL/React.Windows.Desktop.DLL.vcxproj b/vnext/Desktop.DLL/React.Windows.Desktop.DLL.vcxproj index c598ae4e5e7..5376bcd160f 100644 --- a/vnext/Desktop.DLL/React.Windows.Desktop.DLL.vcxproj +++ b/vnext/Desktop.DLL/React.Windows.Desktop.DLL.vcxproj @@ -63,10 +63,8 @@ WIN32; _WINDOWS; _USRDLL; - REACTNATIVEWIN32_EXPORTS; FOLLY_NO_CONFIG; NOMINMAX; - GLOG_NO_ABBREVIATED_SEVERITIES; _HAS_AUTO_PTR_ETC; CHAKRACORE; RN_EXPORT=; @@ -122,21 +120,6 @@ - - {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - - {A990658C-CE31-4BCC-976F-0FC6B1AF693D} - - - {74085F13-2DDE-45E5-A0CA-927AC9D0B953} - - - {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} - - - {11C084A3-A57C-4296-A679-CAC17B603144} - {95048601-C3DC-475F-ADF8-7C0C764C10D5} @@ -169,6 +152,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + diff --git a/vnext/Desktop.DLL/packages.config b/vnext/Desktop.DLL/packages.config index 50494a3bc9d..aa1174628fc 100644 --- a/vnext/Desktop.DLL/packages.config +++ b/vnext/Desktop.DLL/packages.config @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/vnext/Desktop.IntegrationTests/React.Windows.Desktop.IntegrationTests.vcxproj b/vnext/Desktop.IntegrationTests/React.Windows.Desktop.IntegrationTests.vcxproj index 44603739225..a44671c4fd1 100644 --- a/vnext/Desktop.IntegrationTests/React.Windows.Desktop.IntegrationTests.vcxproj +++ b/vnext/Desktop.IntegrationTests/React.Windows.Desktop.IntegrationTests.vcxproj @@ -55,10 +55,8 @@ _WIN32_WINNT=$(WinVer); WIN32; _WINDOWS; - REACTNATIVEWIN32_EXPORTS; FOLLY_NO_CONFIG; NOMINMAX; - GLOG_NO_ABBREVIATED_SEVERITIES; _HAS_AUTO_PTR_ETC; CHAKRACORE; RN_PLATFORM=windesktop; @@ -102,21 +100,9 @@ - - {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - {A990658C-CE31-4BCC-976F-0FC6B1AF693D} - - {74085F13-2DDE-45E5-A0CA-927AC9D0B953} - - - {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} - - - {11C084A3-A57C-4296-A679-CAC17B603144} - {700A84FD-F92A-43F1-8D06-B0E0745DF9B5} diff --git a/vnext/Desktop.UnitTests/React.Windows.Desktop.UnitTests.vcxproj b/vnext/Desktop.UnitTests/React.Windows.Desktop.UnitTests.vcxproj index 1048078ca0f..84f5784e4f1 100644 --- a/vnext/Desktop.UnitTests/React.Windows.Desktop.UnitTests.vcxproj +++ b/vnext/Desktop.UnitTests/React.Windows.Desktop.UnitTests.vcxproj @@ -53,10 +53,8 @@ _WIN32_WINNT=$(WinVer); WIN32; _WINDOWS; - REACTNATIVEWIN32_EXPORTS; FOLLY_NO_CONFIG; NOMINMAX; - GLOG_NO_ABBREVIATED_SEVERITIES; _HAS_AUTO_PTR_ETC; CHAKRACORE; RN_EXPORT=; diff --git a/vnext/Desktop/React.Windows.Desktop.vcxproj b/vnext/Desktop/React.Windows.Desktop.vcxproj index 41a7846d4fd..556cb33f4db 100644 --- a/vnext/Desktop/React.Windows.Desktop.vcxproj +++ b/vnext/Desktop/React.Windows.Desktop.vcxproj @@ -72,10 +72,8 @@ _WIN32_WINNT=$(WinVer); WIN32; _WINDOWS; - REACTNATIVEWIN32_EXPORTS; FOLLY_NO_CONFIG; NOMINMAX; - GLOG_NO_ABBREVIATED_SEVERITIES; _HAS_AUTO_PTR_ETC; CHAKRACORE; RN_PLATFORM=win32; @@ -196,6 +194,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + diff --git a/vnext/IntegrationTests/React.Windows.IntegrationTests.vcxproj b/vnext/IntegrationTests/React.Windows.IntegrationTests.vcxproj index 470ab3aadbd..1023d7466b2 100644 --- a/vnext/IntegrationTests/React.Windows.IntegrationTests.vcxproj +++ b/vnext/IntegrationTests/React.Windows.IntegrationTests.vcxproj @@ -64,9 +64,6 @@ {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - {11C084A3-A57C-4296-A679-CAC17B603144} - diff --git a/vnext/JSI.Desktop.UnitTests/JSI.Desktop.UnitTests.vcxproj b/vnext/JSI.Desktop.UnitTests/JSI.Desktop.UnitTests.vcxproj index 6dbf207ef0d..c51a6f46a48 100644 --- a/vnext/JSI.Desktop.UnitTests/JSI.Desktop.UnitTests.vcxproj +++ b/vnext/JSI.Desktop.UnitTests/JSI.Desktop.UnitTests.vcxproj @@ -26,16 +26,9 @@ - - - - - - - $(ReactNativeWindowsDir);$(ReactNativeWindowsDir)Common;$(ReactNativeWindowsDir)stubs;$(FollyDir);$(ReactNativeDir)\ReactCommon;$(JSI_Source);$(ReactNativeWindowsDir)ReactWindowsCore;$(ReactNativeWindowsDir)\ReactWindowsCore\tracing;$(ReactNativeWindowsDir)include\ReactWindowsCore;$(ReactNativeWindowsDir)Desktop;$(ReactNativeWindowsDir)IntegrationTests;$(ReactNativeWindowsDir)JSI\Shared;$(MSBuildProjectDirectory);$(ReactNativeDir)\ReactCommon\callinvoker;$(IncludePath) true @@ -53,10 +46,8 @@ _WIN32_WINNT=$(WinVer); WIN32; _WINDOWS; - REACTNATIVEWIN32_EXPORTS; FOLLY_NO_CONFIG; NOMINMAX; - GLOG_NO_ABBREVIATED_SEVERITIES; _HAS_AUTO_PTR_ETC; CHAKRACORE; RN_EXPORT=; @@ -73,16 +64,8 @@ -minpdbpathlen:256 - - comsuppw.lib; delayimp.lib; - Shlwapi.lib; - Winhttp.lib; %(AdditionalDependencies) DebugFull @@ -119,21 +102,9 @@ - - {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - - {A990658C-CE31-4BCC-976F-0FC6B1AF693D} - - - {74085F13-2DDE-45E5-A0CA-927AC9D0B953} - {A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} - - {11C084A3-A57C-4296-A679-CAC17B603144} - {95048601-C3DC-475F-ADF8-7C0C764C10D5} @@ -158,6 +129,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + diff --git a/vnext/JSI.Desktop.UnitTests/packages.config b/vnext/JSI.Desktop.UnitTests/packages.config index d9a6b100a5f..87f1304896e 100644 --- a/vnext/JSI.Desktop.UnitTests/packages.config +++ b/vnext/JSI.Desktop.UnitTests/packages.config @@ -6,4 +6,5 @@ + \ No newline at end of file diff --git a/vnext/JSI/Desktop/JSI.Desktop.vcxproj b/vnext/JSI/Desktop/JSI.Desktop.vcxproj index 0737e735265..58788a35444 100644 --- a/vnext/JSI/Desktop/JSI.Desktop.vcxproj +++ b/vnext/JSI/Desktop/JSI.Desktop.vcxproj @@ -74,11 +74,6 @@ - - - {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - @@ -89,6 +84,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + diff --git a/vnext/JSI/Universal/JSI.Universal.vcxproj b/vnext/JSI/Universal/JSI.Universal.vcxproj index 2dbbf006cb2..8ed94f58f44 100644 --- a/vnext/JSI/Universal/JSI.Universal.vcxproj +++ b/vnext/JSI/Universal/JSI.Universal.vcxproj @@ -115,11 +115,6 @@ - - - {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj index 4558c0c563e..06198259254 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj @@ -147,8 +147,6 @@ --> CHAKRACORE;CHAKRACORE_UWP;%(PreprocessorDefinitions) USE_EDGEMODE_JSRT;%(PreprocessorDefinitions) - USE_HERMES;%(PreprocessorDefinitions) - USE_V8;%(PreprocessorDefinitions) REACTWINDOWS_BUILD; RN_PLATFORM=windows; diff --git a/vnext/PropertySheets/React.Cpp.props b/vnext/PropertySheets/React.Cpp.props index 2bb87442726..f191493c0f9 100644 --- a/vnext/PropertySheets/React.Cpp.props +++ b/vnext/PropertySheets/React.Cpp.props @@ -27,7 +27,7 @@ 0.1.6 $(SolutionDir)packages\ReactNative.Hermes.Windows.$(HERMES_Version) - false + false 0.2.7 $(SolutionDir)packages\ReactNative.V8Jsi.Windows.$(V8_Version) @@ -46,6 +46,8 @@ ENABLE_ETW_TRACING;%(PreprocessorDefinitions) ENABLE_JS_SYSTRACE_TO_ETW;WITH_FBSYSTRACE;%(PreprocessorDefinitions) + USE_HERMES;%(PreprocessorDefinitions) + USE_V8;%(PreprocessorDefinitions) diff --git a/vnext/ReactUWP/ReactUWP.vcxproj b/vnext/ReactUWP/ReactUWP.vcxproj index ffddc8d89cb..7045c842381 100644 --- a/vnext/ReactUWP/ReactUWP.vcxproj +++ b/vnext/ReactUWP/ReactUWP.vcxproj @@ -90,8 +90,6 @@ --> CHAKRACORE;CHAKRACORE_UWP;%(PreprocessorDefinitions) USE_EDGEMODE_JSRT;%(PreprocessorDefinitions) - USE_HERMES;%(PreprocessorDefinitions) - USE_V8;%(PreprocessorDefinitions) REACTWINDOWS_BUILD; RN_PLATFORM=windows; diff --git a/vnext/ReactWindows-Desktop.sln b/vnext/ReactWindows-Desktop.sln index 8e60ffd4d45..6e3ddae5d0a 100644 --- a/vnext/ReactWindows-Desktop.sln +++ b/vnext/ReactWindows-Desktop.sln @@ -128,7 +128,6 @@ Global Mso\Mso.vcxitems*{1958ceaa-fbe0-44e3-8a99-90ad85531ffe}*SharedItemsImports = 4 Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9 Chakra\Chakra.vcxitems*{6f354505-fe3a-4bd2-a9a6-d12bbf37a85c}*SharedItemsImports = 4 - Shared\Shared.vcxitems*{6f354505-fe3a-4bd2-a9a6-d12bbf37a85c}*SharedItemsImports = 4 Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9 Chakra\Chakra.vcxitems*{95048601-c3dc-475f-adf8-7c0c764c10d5}*SharedItemsImports = 4 Mso\Mso.vcxitems*{95048601-c3dc-475f-adf8-7c0c764c10d5}*SharedItemsImports = 4 diff --git a/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems b/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems index 13e56fc783b..45f57133a2e 100644 --- a/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems +++ b/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems @@ -66,10 +66,6 @@ - - - - @@ -102,12 +98,10 @@ CHAKRACORE; %(PreprocessorDefinitions) - USE_HERMES;%(PreprocessorDefinitions) $(ReactNativeWindowsDir); $(ReactNativeWindowsDir)Common; $(ReactNativeWindowsDir)Shared; - $(ReactNativeWindowsDir)include; $(ReactNativeWindowsDir)include\ReactWindowsCore; $(ReactNativeDir)\ReactCommon; $(ReactNativeDir)\ReactCommon\callinvoker; @@ -232,12 +226,6 @@ {fca38f3c-7c73-4c47-be4e-32f77fa8538d} - - {a990658c-ce31-4bcc-976f-0fc6b1af693d} - - - {a9d95a91-4db7-4f72-beb6-fe8a5c89bfbd} - diff --git a/vnext/Shared/Shared.vcxitems b/vnext/Shared/Shared.vcxitems index c426153725d..4d31e11fc82 100644 --- a/vnext/Shared/Shared.vcxitems +++ b/vnext/Shared/Shared.vcxitems @@ -8,8 +8,6 @@ %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - USE_HERMES;%(PreprocessorDefinitions) - USE_V8;%(PreprocessorDefinitions) diff --git a/vnext/Universal.UnitTests/React.Windows.Universal.UnitTests.vcxproj b/vnext/Universal.UnitTests/React.Windows.Universal.UnitTests.vcxproj index 51e9f3f11bd..c138c10390e 100644 --- a/vnext/Universal.UnitTests/React.Windows.Universal.UnitTests.vcxproj +++ b/vnext/Universal.UnitTests/React.Windows.Universal.UnitTests.vcxproj @@ -121,9 +121,6 @@ {a990658c-ce31-4bcc-976f-0fc6b1af693d} - - {a9d95a91-4db7-4f72-beb6-fe8a5c89bfbd} - {2d5d43d9-cffc-4c40-b4cd-02efb4e2742b} diff --git a/vnext/V8Inspector/V8Inspector.vcxproj b/vnext/V8Inspector/V8Inspector.vcxproj deleted file mode 100644 index 3522fe72dde..00000000000 --- a/vnext/V8Inspector/V8Inspector.vcxproj +++ /dev/null @@ -1,122 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {F1B91D19-79E4-461B-AC8E-E3E6E747F65F} - Win32Proj - V8Inspector - 10.0.18362.0 - - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - - - - - - NotUsing - false - true - $(ReactNativeDir)\ReactCommon;$(JSI_Source);%(AdditionalIncludeDirectories) - - BOOST_ASIO_DISABLE_BOOST_REGEX; - BOOST_ERROR_CODE_HEADER_ONLY; - BOOST_ASIO_HAS_IOCP; - _WIN32_WINNT=$(WinVer); - WIN32; - _WINDOWS; - _WIN32; - JSI_EXPORT=; - %(PreprocessorDefinitions) - - - false - - - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/vnext/V8Inspector/V8Inspector.vcxproj.filters b/vnext/V8Inspector/V8Inspector.vcxproj.filters deleted file mode 100644 index 1097daff606..00000000000 --- a/vnext/V8Inspector/V8Inspector.vcxproj.filters +++ /dev/null @@ -1,63 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file From d374932510f3cd3377920aa0234f5237f69bfc66 Mon Sep 17 00:00:00 2001 From: React-Native-Windows Bot <53619745+rnbot@users.noreply.github.com> Date: Sun, 10 May 2020 00:05:02 +0000 Subject: [PATCH 03/33] applying package updates ***NO_CI*** --- ...native-windows-2020-05-08-14-17-35-master.json | 8 -------- packages/E2ETest/package.json | 2 +- .../microsoft-reactnative-sampleapps/package.json | 2 +- packages/playground/package.json | 2 +- vnext/CHANGELOG.json | 15 +++++++++++++++ vnext/CHANGELOG.md | 10 +++++++++- vnext/package.json | 2 +- 7 files changed, 28 insertions(+), 13 deletions(-) delete mode 100644 change/react-native-windows-2020-05-08-14-17-35-master.json diff --git a/change/react-native-windows-2020-05-08-14-17-35-master.json b/change/react-native-windows-2020-05-08-14-17-35-master.json deleted file mode 100644 index c55a7882828..00000000000 --- a/change/react-native-windows-2020-05-08-14-17-35-master.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Reenable V8 for desktop projects", - "packageName": "react-native-windows", - "email": "tudorm@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-05-08T21:17:35.875Z" -} diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json index 43cc94f53a4..39106f4510a 100644 --- a/packages/E2ETest/package.json +++ b/packages/E2ETest/package.json @@ -25,7 +25,7 @@ "prompt-sync": "^4.2.0", "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.62" + "react-native-windows": "0.0.0-master.63" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/microsoft-reactnative-sampleapps/package.json b/packages/microsoft-reactnative-sampleapps/package.json index 512f96ab9ca..faf33dc0167 100644 --- a/packages/microsoft-reactnative-sampleapps/package.json +++ b/packages/microsoft-reactnative-sampleapps/package.json @@ -16,7 +16,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.62" + "react-native-windows": "0.0.0-master.63" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/playground/package.json b/packages/playground/package.json index 429fc214d7b..449e7089930 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,7 +11,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.62" + "react-native-windows": "0.0.0-master.63" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json index e5de6cf161b..f1ddb330210 100644 --- a/vnext/CHANGELOG.json +++ b/vnext/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "react-native-windows", "entries": [ + { + "date": "Sun, 10 May 2020 00:05:02 GMT", + "tag": "react-native-windows_v0.0.0-master.63", + "version": "0.0.0-master.63", + "comments": { + "prerelease": [ + { + "comment": "Reenable V8 for desktop projects", + "author": "tudorm@microsoft.com", + "commit": "858fdce423bb4a0eac46dd4eca97adb3b6b042e9", + "package": "react-native-windows" + } + ] + } + }, { "date": "Sat, 09 May 2020 00:04:42 GMT", "tag": "react-native-windows_v0.0.0-master.62", diff --git a/vnext/CHANGELOG.md b/vnext/CHANGELOG.md index 740bdc37cfe..c340b96fa98 100644 --- a/vnext/CHANGELOG.md +++ b/vnext/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - react-native-windows -This log was last generated on Sat, 09 May 2020 00:04:42 GMT and should not be manually modified. +This log was last generated on Sun, 10 May 2020 00:05:02 GMT and should not be manually modified. +## 0.0.0-master.63 + +Sun, 10 May 2020 00:05:02 GMT + +### Changes + +- Reenable V8 for desktop projects (tudorm@microsoft.com) + ## 0.0.0-master.62 Sat, 09 May 2020 00:04:42 GMT diff --git a/vnext/package.json b/vnext/package.json index b55fcc9940c..c3e32b9805b 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.0.0-master.62", + "version": "0.0.0-master.63", "license": "MIT", "repository": { "type": "git", From 487e8d58c4d62dc26dd79ed55b0b8fa41a3fb7d7 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Sat, 9 May 2020 19:01:47 -0700 Subject: [PATCH 04/33] update masters --- .../masters/ControlStyleRegularBorder.json | 111 ++---------------- .../masters/ControlStyleRoundBorder.json | 111 ++---------------- .../Assets/TreeDump/masters/ImageRTL.json | 1 + .../TreeDump/masters/ImageWithBorder.json | 1 + .../ImageWithoutBorder-Subsequent.json | 1 + .../TreeDump/masters/ImageWithoutBorder.json | 1 + .../windows/TreeDumpLibrary/TreeDumpHelper.cs | 2 - 7 files changed, 26 insertions(+), 202 deletions(-) diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json index 818fa573d29..6442cc408f4 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, + "AutomationId": "ControlStyleView", "children": [ { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", @@ -113,6 +114,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [20, 16], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -157,6 +159,7 @@ "Margin": "0,0,0,0", "Padding": "10,10,10,10", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, @@ -283,56 +286,6 @@ "RenderSize": [798, 48], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -350,6 +303,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [798, 48], + "Text": "TextBox", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -531,56 +485,6 @@ "RenderSize": [798, 48], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -598,6 +502,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [798, 48], + "Text": "Password", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -699,6 +604,7 @@ "Name": "DateText", "Padding": "12,0,0,2", "RenderSize": [90, 21], + "Text": "select a date", "VerticalAlignment": "Center", "Visibility": "Visible" }, @@ -738,6 +644,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -780,6 +687,7 @@ "Margin": "0,0,0,0", "Padding": "12,5,0,7", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Top", "Visibility": "Visible", "Width": 800, @@ -859,6 +767,7 @@ "Name": "PlaceholderTextBlock", "Padding": "0,0,0,0", "RenderSize": [756, 19], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible" } @@ -878,6 +787,7 @@ "Name": "EditableText", "Padding": "11,5,32,6", "RenderSize": [0, 0], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Collapsed" }, @@ -934,6 +844,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json index 3e26498c954..398d7cb8609 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, + "AutomationId": "ControlStyleView", "children": [ { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", @@ -113,6 +114,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [20, 16], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -157,6 +159,7 @@ "Margin": "0,0,0,0", "Padding": "10,10,10,10", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, @@ -283,56 +286,6 @@ "RenderSize": [780, 30], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -350,6 +303,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [780, 39], + "Text": "TextBox", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -531,56 +485,6 @@ "RenderSize": [780, 30], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -598,6 +502,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [780, 39], + "Text": "Password", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -699,6 +604,7 @@ "Name": "DateText", "Padding": "12,0,0,2", "RenderSize": [90, 21], + "Text": "select a date", "VerticalAlignment": "Center", "Visibility": "Visible" }, @@ -738,6 +644,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -780,6 +687,7 @@ "Margin": "0,0,0,0", "Padding": "12,5,0,7", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Top", "Visibility": "Visible", "Width": 800, @@ -859,6 +767,7 @@ "Name": "PlaceholderTextBlock", "Padding": "0,0,0,0", "RenderSize": [756, 19], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible" } @@ -878,6 +787,7 @@ "Name": "EditableText", "Padding": "11,5,32,6", "RenderSize": [0, 0], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Collapsed" }, @@ -934,6 +844,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json index c00ab2049da..e6560044fe8 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json index 753214da826..9c87e39efe5 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json index c00ab2049da..e6560044fe8 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json index 9406a02556a..9be2fa56439 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Windows.UI.Xaml.DependencyObject" diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs index 55daeb7c57f..e2d60587cc9 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs @@ -103,9 +103,7 @@ public static bool DumpsAreEqual(string dumpExpectedText, string dumpText) private static bool JsonComparesEqual(IJsonValue expected, IJsonValue actual, string keyName) { - //const string anything = "‎"; const string Anything = ""; - //System.Diagnostics.Debug.Assert(anything == Anything); if (expected.ValueType == JsonValueType.String && Regex.Replace(expected.GetString(), @"\p{C}", "") == Anything) { Debug.WriteLine($"Skipping ignored value: {actual.ValueType} {actual}"); From cf658bab8ef4045251876a1408c71aefc7539cd7 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Mon, 11 May 2020 10:10:29 -0700 Subject: [PATCH 05/33] Improve run_wdio to print out failed tests (#4843) * Improve run_wdio to print out failed tests --- packages/E2ETest/run_wdio.js | 95 +++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/packages/E2ETest/run_wdio.js b/packages/E2ETest/run_wdio.js index 56a33f269f5..aec747f94f2 100644 --- a/packages/E2ETest/run_wdio.js +++ b/packages/E2ETest/run_wdio.js @@ -4,10 +4,11 @@ const xml2js = require('xml2js'); const parser = new xml2js.Parser({ attrkey: 'ATTR' }); const child_process = require('child_process'); const prompt = require('prompt-sync')(); +const chalk = require('chalk'); const specFolder = 'wdio/test'; -function GetMetadata(specPath) { +function getMetadata(specPath) { const contents = fs.readFileSync(specPath); const metadataTag = '// @metadata '; const metadataStart = contents.indexOf(metadataTag); @@ -29,31 +30,31 @@ const filters = { // Returns true if the spec is to run. // Specs marked SkipCI are excluded from CI (identified by environment variables in the ADO lab) -function FilterSpec(specPath) { - const metadata = GetMetadata(specPath); - for (let i = 0; i < metadata.length; i++) { - if (filters[metadata[i]](specPath)) { +function filterSpec(specPath) { + const metadata = getMetadata(specPath); + for (const metadataElement of metadata) { + if (filters[metadataElement](specPath)) { return false; } } return true; } -function SelectSpecs(folder) { +function selectSpecs(folder) { let specs = []; if (process.argv.length > 2) { specs = process.argv.splice(2).map(spec => spec + '.spec.ts'); } else { specs = fs.readdirSync(folder).filter(x => x.endsWith('.spec.ts')); } - specs = specs.map(spec => path.join(folder, spec)).filter(FilterSpec); + specs = specs.map(spec => path.join(folder, spec)).filter(filterSpec); return specs; } -let opts = SelectSpecs(specFolder); +let opts = selectSpecs(specFolder); console.log(`Selected tests: ${opts}`); -function OverrideHyperV() { +function ensureRunningInHyperV() { const baseboardMfr = child_process .execSync('powershell.exe (gwmi Win32_BaseBoard).Manufacturer') .toString() @@ -69,26 +70,41 @@ function OverrideHyperV() { } } -OverrideHyperV(); - const Launcher = require('@wdio/cli').default; const wdio = new Launcher('wdio.conf.js', { specs: opts }); function parseLog(logfile) { const xmlString = fs.readFileSync(logfile); - let name; + let failures = {}; parser.parseString(xmlString, (err, res) => { if (!res.testsuites) { - name = 'something went wrong'; + console.error(`Something went wrong processing file ${logfile}`); } else { - const attr = res.testsuites.testsuite[0].ATTR; - if (attr.errors > 0 || attr.failures > 0) { - name = attr.name; + for (const testsuite of res.testsuites.testsuite) { + const attr = testsuite.ATTR; + + if (attr.errors > 0 || attr.failures > 0) { + const name = attr.name; + failures[name] = {}; + + for (const testcase of testsuite.testcases) { + if (testcase.error && testcase.error[0].ATTR) { + failures[name].testcase = testcase.ATTR.name; + failures[name].error = testcase.error[0].ATTR.message; + const systemErr = testcase['system-err'][0]; + const stack = systemErr.substr( + systemErr.indexOf('\n at ') + 1 + ); + failures[name].stack = stack; + } + } + } } } }); - return name; + + return failures; } function parseLogs() { @@ -100,20 +116,41 @@ function parseLogs() { return names; } -function Process(code) { +function printFailedTests(ft) { + for (const key in ft) { + console.log(chalk.redBright(key)); + console.log( + ' ', + chalk.underline('testcase'), + chalk.bold(ft[key].testcase) + ); + console.log(' ', chalk.underline('error'), chalk.bold(ft[key].error)); + console.log(' ', chalk.underline('stack')); + console.log(ft[key].stack); + } +} + +function doProcess(code) { const failedTests = parseLogs(); - for (let i = 0; i < failedTests.length; i++) { - console.log(`Failed test: ${failedTests[i]}`); + for (const failedTest of failedTests) { + console.log('Failed tests: '); + printFailedTests(failedTest); } process.exit(code); } -wdio.run().then( - code => { - Process(code); - }, - error => { - console.error('Launcher failed to start the test', error.stacktrace); - process.exit(1); - } -); +function runWdio() { + ensureRunningInHyperV(); + + wdio.run().then( + code => { + doProcess(code); + }, + error => { + console.error('Launcher failed to start the test', error.stacktrace); + process.exit(1); + } + ); +} + +runWdio(); From c40cc0ea1de8b4acb830939ba79146739f438111 Mon Sep 17 00:00:00 2001 From: lamxdoan Date: Mon, 11 May 2020 10:12:05 -0700 Subject: [PATCH 06/33] Fire onLoad event when a bitmap image is opened (#4750) * Fire onLoad event when a bitmap image is opeed * Change files * add imageFailed * remove firing of onload events in the createImageBrush block so that load events don't fire twice. --- ...ndows-2020-04-29-15-37-41-imageonload.json | 9 +++++ vnext/ReactUWP/Views/Image/ReactImage.cpp | 37 ++++++++++--------- vnext/ReactUWP/Views/Image/ReactImage.h | 2 +- 3 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 change/react-native-windows-2020-04-29-15-37-41-imageonload.json diff --git a/change/react-native-windows-2020-04-29-15-37-41-imageonload.json b/change/react-native-windows-2020-04-29-15-37-41-imageonload.json new file mode 100644 index 00000000000..714ebefda8d --- /dev/null +++ b/change/react-native-windows-2020-04-29-15-37-41-imageonload.json @@ -0,0 +1,9 @@ +{ + "type": "prerelease", + "comment": "Fire onLoad event when a bitmap image is opeed", + "packageName": "react-native-windows", + "email": "lamdoan@microsoft.com", + "commit": "22edad7ea69232ae7636424c237df4eee7577f54", + "dependentChangeType": "patch", + "date": "2020-04-29T22:37:41.642Z" +} \ No newline at end of file diff --git a/vnext/ReactUWP/Views/Image/ReactImage.cpp b/vnext/ReactUWP/Views/Image/ReactImage.cpp index 791a3776ecc..7ec70a89aca 100644 --- a/vnext/ReactUWP/Views/Image/ReactImage.cpp +++ b/vnext/ReactUWP/Views/Image/ReactImage.cpp @@ -213,10 +213,8 @@ winrt::fire_and_forget ReactImage::SetBackground(bool fireLoadEndEvent) { if (createImageBrush) { imageBrush = winrt::ImageBrush{}; - // ImageOpened and ImageFailed are mutually exclusive. One event of the other will - // always fire whenever an ImageBrush has the ImageSource value set or reset. - strong_this->m_imageBrushOpenedRevoker = imageBrush.ImageOpened( - winrt::auto_revoke, [weak_this, imageBrush, fireLoadEndEvent](const auto &, const auto &) { + strong_this->m_imageBrushOpenedRevoker = + imageBrush.ImageOpened(winrt::auto_revoke, [weak_this, imageBrush](const auto &, const auto &) { if (auto strong_this{weak_this.get()}) { if (auto bitmap{imageBrush.ImageSource().try_as()}) { strong_this->m_imageSource.height = bitmap.PixelHeight(); @@ -224,18 +222,6 @@ winrt::fire_and_forget ReactImage::SetBackground(bool fireLoadEndEvent) { } imageBrush.Stretch(strong_this->ResizeModeToStretch(strong_this->m_resizeMode)); - - if (fireLoadEndEvent) { - strong_this->m_onLoadEndEvent(*strong_this, true); - } - } - }); - - strong_this->m_imageBrushFailedRevoker = - imageBrush.ImageFailed(winrt::auto_revoke, [weak_this, fireLoadEndEvent](const auto &, const auto &) { - const auto strong_this{weak_this.get()}; - if (strong_this && fireLoadEndEvent) { - strong_this->m_onLoadEndEvent(*strong_this, false); } }); } @@ -274,7 +260,24 @@ winrt::fire_and_forget ReactImage::SetBackground(bool fireLoadEndEvent) { bitmapImage = winrt::BitmapImage{}; strong_this->m_bitmapImageOpened = bitmapImage.ImageOpened( - winrt::auto_revoke, [imageBrush](const auto &, const auto &) { imageBrush.Opacity(1); }); + winrt::auto_revoke, [imageBrush, weak_this, fireLoadEndEvent](const auto &, const auto &) { + imageBrush.Opacity(1); + + auto strong_this{weak_this.get()}; + if (strong_this && fireLoadEndEvent) { + strong_this->m_onLoadEndEvent(*strong_this, true); + } + }); + + strong_this->m_bitmapImageFailed = bitmapImage.ImageFailed( + winrt::auto_revoke, [imageBrush, weak_this, fireLoadEndEvent](const auto &, const auto &) { + imageBrush.Opacity(1); + + auto strong_this{weak_this.get()}; + if (strong_this && fireLoadEndEvent) { + strong_this->m_onLoadEndEvent(*strong_this, false); + } + }); imageBrush.ImageSource(bitmapImage); } diff --git a/vnext/ReactUWP/Views/Image/ReactImage.h b/vnext/ReactUWP/Views/Image/ReactImage.h index 4a8ac619460..e73ca246581 100644 --- a/vnext/ReactUWP/Views/Image/ReactImage.h +++ b/vnext/ReactUWP/Views/Image/ReactImage.h @@ -67,8 +67,8 @@ struct ReactImage : xaml::Controls::GridT { xaml::FrameworkElement::SizeChanged_revoker m_sizeChangedRevoker; xaml::Media::LoadedImageSurface::LoadCompleted_revoker m_surfaceLoadedRevoker; xaml::Media::Imaging::BitmapImage::ImageOpened_revoker m_bitmapImageOpened; + xaml::Media::Imaging::BitmapImage::ImageFailed_revoker m_bitmapImageFailed; xaml::Media::ImageBrush::ImageOpened_revoker m_imageBrushOpenedRevoker; - xaml::Media::ImageBrush::ImageFailed_revoker m_imageBrushFailedRevoker; xaml::Media::Imaging::SvgImageSource::Opened_revoker m_svgImageSourceOpenedRevoker; xaml::Media::Imaging::SvgImageSource::OpenFailed_revoker m_svgImageSourceOpenFailedRevoker; }; From 55091b9447d741fc0e9c23acb8dfdee53ad11598 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Mon, 11 May 2020 12:55:05 -0700 Subject: [PATCH 07/33] Expose ability for apps to provide their own RedBox implementation (#4786) * Expose ability for apps to provide their own RedBox implementation * Change files * minor changes * Code review feedback * minor fix * format fixes * minor change * minor fix * minor fix * minor fix --- ...020-05-04-12-54-41-publiccustomredbox.json | 8 + packages/scripts/formatFiles.js | 1 + .../Microsoft.ReactNative.vcxproj | 11 ++ .../Microsoft.ReactNative.vcxproj.filters | 1 + .../ReactHost/ReactInstanceWin.cpp | 2 +- .../ReactInstanceSettings.h | 12 ++ .../ReactInstanceSettings.idl | 2 + .../Microsoft.ReactNative/ReactNativeHost.cpp | 6 + vnext/Microsoft.ReactNative/RedBox.cpp | 162 +++++++++++++----- vnext/Microsoft.ReactNative/RedBox.h | 7 +- vnext/Microsoft.ReactNative/RedBoxHandler.cpp | 63 +++++++ vnext/Microsoft.ReactNative/RedBoxHandler.h | 26 +++ vnext/Microsoft.ReactNative/RedBoxHandler.idl | 43 +++++ vnext/ReactUWP/Base/UwpReactInstance.cpp | 4 +- vnext/ReactWindowsCore/DevSettings.h | 2 +- .../{RedBoxHandler.h => IRedBoxHandler.h} | 2 +- .../Modules/ExceptionsManagerModule.h | 2 +- .../ReactWindowsCore.vcxitems | 2 +- .../ReactWindowsCore.vcxproj.filters | 2 +- vnext/Scripts/ReactWin32.nuspec | 2 +- 20 files changed, 309 insertions(+), 51 deletions(-) create mode 100644 change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json create mode 100644 vnext/Microsoft.ReactNative/RedBoxHandler.cpp create mode 100644 vnext/Microsoft.ReactNative/RedBoxHandler.h create mode 100644 vnext/Microsoft.ReactNative/RedBoxHandler.idl rename vnext/ReactWindowsCore/{RedBoxHandler.h => IRedBoxHandler.h} (94%) diff --git a/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json b/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json new file mode 100644 index 00000000000..dc9e8030a2f --- /dev/null +++ b/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Expose ability for apps to provide their own RedBox implementation", + "packageName": "react-native-windows", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-04T19:54:41.414Z" +} diff --git a/packages/scripts/formatFiles.js b/packages/scripts/formatFiles.js index 86c16d088e0..7bce4725db7 100644 --- a/packages/scripts/formatFiles.js +++ b/packages/scripts/formatFiles.js @@ -35,6 +35,7 @@ function queryNoOpenFiles() { if (opened) { console.error('The following files have incorrect formatting:'); console.error(opened); + console.error('Running `yarn format` from the repo root should fix this.'); process.exit(2); } } diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj index 06198259254..68d21f19ac0 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj @@ -340,6 +340,10 @@ ReactInstanceSettings.idl Code + + RedBoxHandler.idl + Code + ReactNativeHost.idl Code @@ -501,6 +505,10 @@ ReactInstanceSettings.idl Code + + RedBoxHandler.idl + Code + ReactNativeHost.idl Code @@ -558,6 +566,9 @@ Designer + + Designer + Designer diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters index f5cee04be05..de2019f2870 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters @@ -688,6 +688,7 @@ + diff --git a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp index 957aca066f2..0218b9b075c 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +++ b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp @@ -517,7 +517,7 @@ std::shared_ptr ReactInstanceWin::GetRedBoxHandler() noexcept { return m_options.RedBoxHandler; } else if (m_options.DeveloperSettings.IsDevModeEnabled) { auto localWkReactHost = m_weakReactHost; - return CreateRedBoxHandler(std::move(localWkReactHost), m_uiMessageThread.LoadWithLock()); + return CreateDefaultRedBoxHandler(std::move(localWkReactHost)); } else { return {}; } diff --git a/vnext/Microsoft.ReactNative/ReactInstanceSettings.h b/vnext/Microsoft.ReactNative/ReactInstanceSettings.h index daeb91102b9..1e828273511 100644 --- a/vnext/Microsoft.ReactNative/ReactInstanceSettings.h +++ b/vnext/Microsoft.ReactNative/ReactInstanceSettings.h @@ -80,6 +80,9 @@ struct ReactInstanceSettings : ReactInstanceSettingsT { uint16_t DebuggerPort() noexcept; void DebuggerPort(uint16_t value) noexcept; + IRedBoxHandler RedBoxHandler() noexcept; + void RedBoxHandler(IRedBoxHandler const &value) noexcept; + private: IReactPropertyBag m_properties{ReactPropertyBagHelper::CreatePropertyBag()}; hstring m_mainComponentName{}; @@ -100,6 +103,7 @@ struct ReactInstanceSettings : ReactInstanceSettingsT { hstring m_debugBundlePath{}; hstring m_bundleRootPath{}; uint16_t m_debuggerPort{9229}; + IRedBoxHandler m_redBoxHandler{nullptr}; }; } // namespace winrt::Microsoft::ReactNative::implementation @@ -264,4 +268,12 @@ inline void ReactInstanceSettings::DebuggerPort(uint16_t value) noexcept { m_debuggerPort = value; } +inline IRedBoxHandler ReactInstanceSettings::RedBoxHandler() noexcept { + return m_redBoxHandler; +} + +inline void ReactInstanceSettings::RedBoxHandler(IRedBoxHandler const &value) noexcept { + m_redBoxHandler = value; +} + } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl index 22887666ca3..f388e735f29 100644 --- a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl +++ b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import "RedBoxHandler.idl"; import "IReactPropertyBag.idl"; namespace Microsoft.ReactNative { @@ -29,5 +30,6 @@ namespace Microsoft.ReactNative { String DebugBundlePath { get; set; }; String BundleRootPath { get; set; }; UInt16 DebuggerPort { get; set; }; + Microsoft.ReactNative.IRedBoxHandler RedBoxHandler { get; set; }; } } diff --git a/vnext/Microsoft.ReactNative/ReactNativeHost.cpp b/vnext/Microsoft.ReactNative/ReactNativeHost.cpp index 6812a46bef3..a7a1c9f3c99 100644 --- a/vnext/Microsoft.ReactNative/ReactNativeHost.cpp +++ b/vnext/Microsoft.ReactNative/ReactNativeHost.cpp @@ -6,6 +6,7 @@ #include "ReactNativeHost.g.cpp" #include "ReactPackageBuilder.h" +#include "RedBox.h" using namespace winrt; using namespace Windows::Foundation::Collections; @@ -78,6 +79,10 @@ void ReactNativeHost::ReloadInstance() noexcept { legacySettings.UseWebDebugger = m_instanceSettings.UseWebDebugger(); legacySettings.DebuggerPort = m_instanceSettings.DebuggerPort(); + if (m_instanceSettings.RedBoxHandler()) { + legacySettings.RedBoxHandler = std::move(Mso::React::CreateRedBoxHandler(m_instanceSettings.RedBoxHandler())); + } + Mso::React::ReactOptions reactOptions{}; reactOptions.Properties = m_instanceSettings.Properties(); reactOptions.DeveloperSettings.IsDevModeEnabled = legacySettings.EnableDeveloperMenu; @@ -91,6 +96,7 @@ void ReactNativeHost::ReloadInstance() noexcept { reactOptions.DeveloperSettings.DebugHost = legacySettings.DebugHost; reactOptions.BundleRootPath = legacySettings.BundleRootPath; reactOptions.DeveloperSettings.DebuggerPort = legacySettings.DebuggerPort; + reactOptions.RedBoxHandler = legacySettings.RedBoxHandler; reactOptions.LegacySettings = std::move(legacySettings); diff --git a/vnext/Microsoft.ReactNative/RedBox.cpp b/vnext/Microsoft.ReactNative/RedBox.cpp index 0c1c327cb24..699454c743e 100644 --- a/vnext/Microsoft.ReactNative/RedBox.cpp +++ b/vnext/Microsoft.ReactNative/RedBox.cpp @@ -4,6 +4,7 @@ #include "RedBox.h" #include #include +#include #include #include #include @@ -18,10 +19,10 @@ namespace Mso::React { struct RedBox : public std::enable_shared_from_this { RedBox( - Mso::WeakPtr weakReactHost, + const Mso::WeakPtr &weakReactHost, Mso::Functor &&onClosedCallback, ErrorInfo &&errorInfo) noexcept - : m_weakReactHost(std::move(weakReactHost)), + : m_weakReactHost(weakReactHost), m_onClosedCallback(std::move(onClosedCallback)), m_errorInfo(std::move(errorInfo)) {} @@ -356,26 +357,22 @@ struct RedBox : public std::enable_shared_from_this { /* * This class is implemented such that the methods on IRedBoxHandler are thread safe. */ -struct RedBoxHandler : public std::enable_shared_from_this, IRedBoxHandler { - RedBoxHandler( - Mso::WeakPtr weakReactHost, - std::shared_ptr uiMessageQueue) noexcept - : m_weakReactHost(std::move(weakReactHost)), m_wkUIMessageQueue(std::move(uiMessageQueue)) {} +struct DefaultRedBoxHandler : public std::enable_shared_from_this, IRedBoxHandler { + DefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept + : m_weakReactHost(std::move(weakReactHost)) {} - ~RedBoxHandler() { + ~DefaultRedBoxHandler() { // Hide any currently showing redboxes std::vector> redboxes; { std::scoped_lock lock{m_lockRedBox}; std::swap(m_redboxes, redboxes); } - if (auto uiQueue = m_wkUIMessageQueue.lock()) { - uiQueue->runOnQueue([redboxes = std::move(redboxes)]() { - for (const auto redbox : redboxes) { - redbox->Dismiss(); - } - }); - } + Mso::DispatchQueue::MainUIQueue().Post([redboxes = std::move(redboxes)]() { + for (const auto redbox : redboxes) { + redbox->Dismiss(); + } + }); } virtual void showNewError(ErrorInfo &&info, ErrorType /*exceptionType*/) override { @@ -394,7 +391,7 @@ struct RedBoxHandler : public std::enable_shared_from_this, IRedB showTopJSError(); } - virtual bool isDevSupportEnabled() override { + virtual bool isDevSupportEnabled() const override { if (auto reactHost = m_weakReactHost.GetStrongPtr()) { return reactHost->Options().DeveloperSettings.IsDevModeEnabled; } @@ -414,28 +411,26 @@ struct RedBoxHandler : public std::enable_shared_from_this, IRedB } } if (redbox) { - if (auto uiQueue = m_wkUIMessageQueue.lock()) { - uiQueue->runOnQueue([redboxCaptured = std::move(redbox), errorInfo = std::move(info)]() { - redboxCaptured->UpdateError(std::move(errorInfo)); - }); - } + Mso::DispatchQueue::MainUIQueue().Post([redboxCaptured = std::move(redbox), errorInfo = std::move(info)]() { + redboxCaptured->UpdateError(std::move(errorInfo)); + }); } } virtual void dismissRedbox() override { - if (auto uiQueue = m_wkUIMessageQueue.lock()) { - uiQueue->runOnQueue([&]() { - std::scoped_lock lock{m_lockRedBox}; - if (!m_redboxes.empty()) - m_redboxes[0]->Dismiss(); - }); - } + Mso::DispatchQueue::MainUIQueue().Post([wkthis = std::weak_ptr(shared_from_this())]() { + if (auto pthis = wkthis.lock()) { + std::scoped_lock lock{pthis->m_lockRedBox}; + if (!pthis->m_redboxes.empty()) + pthis->m_redboxes[0]->Dismiss(); + } + }); } private: // When notified by a redbox that its been dismisssed void onDismissedCallback(uint32_t id) noexcept { - // Save a local ref, so if we are removing the last redbox which could hold the last ref to the RedBoxHandler + // Save a local ref, so if we are removing the last redbox which could hold the last ref to the DefaultRedBoxHandler // We ensure that we exit the mutex before the handler is destroyed. std::shared_ptr redbox; { @@ -463,25 +458,114 @@ struct RedBoxHandler : public std::enable_shared_from_this, IRedB } } - if (auto uiQueue = m_wkUIMessageQueue.lock()) { - if (m_showingRedBox || !redbox) // Only show one redbox at a time - return; - m_showingRedBox = true; - uiQueue->runOnQueue([redboxCaptured = std::move(redbox)]() { redboxCaptured->ShowNewJSError(); }); - } + if (m_showingRedBox || !redbox) // Only show one redbox at a time + return; + m_showingRedBox = true; + + Mso::DispatchQueue::MainUIQueue().Post( + [redboxCaptured = std::move(redbox)]() { redboxCaptured->ShowNewJSError(); }); } bool m_showingRedBox = false; // Access from UI Thread only std::mutex m_lockRedBox; std::vector> m_redboxes; // Protected by m_lockRedBox const Mso::WeakPtr m_weakReactHost; - const std::weak_ptr m_wkUIMessageQueue; +}; + +struct RedBoxErrorFrameInfo + : public winrt::implements { + RedBoxErrorFrameInfo(Mso::React::ErrorFrameInfo &&errorFrameInfo) : m_frame(std::move(errorFrameInfo)) {} + + winrt::hstring File() const noexcept { + return ::Microsoft::Common::Unicode::Utf8ToUtf16(m_frame.File).c_str(); + } + + winrt::hstring Method() const noexcept { + return ::Microsoft::Common::Unicode::Utf8ToUtf16(m_frame.Method).c_str(); + } + + uint32_t Line() const noexcept { + return m_frame.Line; + } + + uint32_t Column() const noexcept { + return m_frame.Column; + } + + private: + Mso::React::ErrorFrameInfo m_frame; +}; + +struct RedBoxErrorInfo : public winrt::implements { + RedBoxErrorInfo(Mso::React::ErrorInfo &&errorInfo) : m_errorInfo(std::move(errorInfo)) {} + + winrt::hstring Message() const noexcept { + return ::Microsoft::Common::Unicode::Utf8ToUtf16(m_errorInfo.Message).c_str(); + } + + uint32_t Id() const noexcept { + return m_errorInfo.Id; + } + + winrt::Windows::Foundation::Collections::IVectorView + Callstack() noexcept { + if (!m_callstack) { + m_callstack = winrt::single_threaded_vector(); + for (auto frame : m_errorInfo.Callstack) { + m_callstack.Append(winrt::make(std::move(frame))); + } + } + + return m_callstack.GetView(); + } + + private: + winrt::Windows::Foundation::Collections::IVector m_callstack{ + nullptr}; + + Mso::React::ErrorInfo m_errorInfo; +}; + +struct RedBoxHandler : public Mso::React::IRedBoxHandler { + RedBoxHandler(winrt::Microsoft::ReactNative::IRedBoxHandler const &redBoxHandler) : m_redBoxHandler(redBoxHandler) {} + + static_assert( + static_cast(Mso::React::ErrorType::JSFatal) == + static_cast(winrt::Microsoft::ReactNative::RedBoxErrorType::JavaScriptFatal)); + static_assert( + static_cast(Mso::React::ErrorType::JSSoft) == + static_cast(winrt::Microsoft::ReactNative::RedBoxErrorType::JavaScriptSoft)); + static_assert( + static_cast(Mso::React::ErrorType::Native) == + static_cast(winrt::Microsoft::ReactNative::RedBoxErrorType::Native)); + + virtual void showNewError(Mso::React::ErrorInfo &&info, Mso::React::ErrorType errorType) override { + m_redBoxHandler.ShowNewError( + winrt::make(std::move(info)), + static_cast(static_cast(errorType))); + } + virtual bool isDevSupportEnabled() const override { + return m_redBoxHandler.IsDevSupportEnabled(); + } + virtual void updateError(Mso::React::ErrorInfo &&info) override { + m_redBoxHandler.UpdateError(winrt::make(std::move(info))); + } + + virtual void dismissRedbox() override { + m_redBoxHandler.DismissRedBox(); + } + + private: + winrt::Microsoft::ReactNative::IRedBoxHandler m_redBoxHandler; }; std::shared_ptr CreateRedBoxHandler( - Mso::WeakPtr &&weakReactHost, - std::shared_ptr &&uiMessageQueue) noexcept { - return std::make_shared(std::move(weakReactHost), std::move(uiMessageQueue)); + winrt::Microsoft::ReactNative::IRedBoxHandler const &redBoxHandler) noexcept { + return std::make_shared(redBoxHandler); +} + +std::shared_ptr CreateDefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept { + return std::make_shared(std::move(weakReactHost)); } } // namespace Mso::React diff --git a/vnext/Microsoft.ReactNative/RedBox.h b/vnext/Microsoft.ReactNative/RedBox.h index 8be0393b921..0a14590aaea 100644 --- a/vnext/Microsoft.ReactNative/RedBox.h +++ b/vnext/Microsoft.ReactNative/RedBox.h @@ -2,13 +2,14 @@ // Licensed under the MIT License. #pragma once #include +#include "IRedBoxHandler.h" #include "ReactHost/React.h" -#include "RedBoxHandler.h" namespace Mso::React { std::shared_ptr CreateRedBoxHandler( - Mso::WeakPtr &&weakReactHost, - std::shared_ptr &&uiMessageQueue) noexcept; + winrt::Microsoft::ReactNative::IRedBoxHandler const &redBoxHandler) noexcept; + +std::shared_ptr CreateDefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept; } // namespace Mso::React diff --git a/vnext/Microsoft.ReactNative/RedBoxHandler.cpp b/vnext/Microsoft.ReactNative/RedBoxHandler.cpp new file mode 100644 index 00000000000..945bece5241 --- /dev/null +++ b/vnext/Microsoft.ReactNative/RedBoxHandler.cpp @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" +#include "RedBoxHandler.h" +#if __has_include("RedBoxHelper.g.cpp") +#include "RedBoxHelper.g.cpp" +#endif + +#include +#include +#include + +namespace winrt::Microsoft::ReactNative::implementation { + +Mso::React::ErrorInfo CreateErrorInfo(const IRedBoxErrorInfo &info) { + Mso::React::ErrorInfo ei; + ei.Id = info.Id(); + ei.Message = ::Microsoft::Common::Unicode::Utf16ToUtf8(info.Message()); + for (const auto &frame : info.Callstack()) { + Mso::React::ErrorFrameInfo efi; + efi.Method = ::Microsoft::Common::Unicode::Utf16ToUtf8(frame.Method()); + efi.File = ::Microsoft::Common::Unicode::Utf16ToUtf8(frame.File()); + efi.Line = frame.Line(); + efi.Column = frame.Column(); + ei.Callstack.push_back(std::move(efi)); + } + return ei; +} + +struct DefaultRedBoxHandler : winrt::implements { + DefaultRedBoxHandler(winrt::Microsoft::ReactNative::ReactNativeHost const &host) noexcept { + auto hostImpl = winrt::get_self(host); + Mso::WeakPtr wkHost(hostImpl->ReactHost()); + m_redBoxHandler = Mso::React::CreateDefaultRedBoxHandler(std::move(wkHost)); + } + + void ShowNewError(IRedBoxErrorInfo const &info, RedBoxErrorType type) noexcept { + m_redBoxHandler->showNewError( + CreateErrorInfo(info), static_cast(static_cast(type))); + } + + bool IsDevSupportEnabled() noexcept { + return m_redBoxHandler->isDevSupportEnabled(); + } + + void UpdateError(IRedBoxErrorInfo const &info) noexcept { + m_redBoxHandler->updateError(std::move(CreateErrorInfo(info))); + } + + void DismissRedBox() noexcept { + m_redBoxHandler->dismissRedbox(); + } + + private: + std::shared_ptr m_redBoxHandler; +}; + +IRedBoxHandler RedBoxHelper::CreateDefaultHandler(winrt::Microsoft::ReactNative::ReactNativeHost const &host) noexcept { + return winrt::make(host); +} + +} // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/RedBoxHandler.h b/vnext/Microsoft.ReactNative/RedBoxHandler.h new file mode 100644 index 00000000000..e8aa4b1f6ac --- /dev/null +++ b/vnext/Microsoft.ReactNative/RedBoxHandler.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "RedBoxHelper.g.h" + +namespace Mso::React { +struct IRedBoxHandler; +} + +namespace winrt::Microsoft::ReactNative::implementation { + +struct RedBoxHelper : RedBoxHelperT { + RedBoxHelper() = default; + + static IRedBoxHandler CreateDefaultHandler(winrt::Microsoft::ReactNative::ReactNativeHost const &host) noexcept; +}; + +} // namespace winrt::Microsoft::ReactNative::implementation + +namespace winrt::Microsoft::ReactNative::factory_implementation { + +struct RedBoxHelper : RedBoxHelperT {}; + +} // namespace winrt::Microsoft::ReactNative::factory_implementation diff --git a/vnext/Microsoft.ReactNative/RedBoxHandler.idl b/vnext/Microsoft.ReactNative/RedBoxHandler.idl new file mode 100644 index 00000000000..0092086437e --- /dev/null +++ b/vnext/Microsoft.ReactNative/RedBoxHandler.idl @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import "ReactNativeHost.idl"; + +namespace Microsoft.ReactNative { + + enum RedBoxErrorType { + JavaScriptFatal, // A JS Exception was thrown or otherwise fatal error + JavaScriptSoft, // An error coming from JS that isn't fatal, such as console.error + Native, + }; + + [webhosthidden] interface IRedBoxErrorFrameInfo { + String File { get; }; + String Method { get; }; + UInt32 Line { get; }; + UInt32 Column { get; }; + } + + [webhosthidden] interface IRedBoxErrorInfo { + String Message { get; }; + UInt32 Id { get; }; + IVectorView Callstack { get; }; + } + + [webhosthidden] + interface IRedBoxHandler + { + void ShowNewError(IRedBoxErrorInfo info, RedBoxErrorType type); + Boolean IsDevSupportEnabled { get; }; + void UpdateError(IRedBoxErrorInfo info); + void DismissRedBox(); + } + + [webhosthidden] + [default_interface] + runtimeclass RedBoxHelper { + RedBoxHelper(); + static IRedBoxHandler CreateDefaultHandler(Microsoft.ReactNative.ReactNativeHost host); + } + +} diff --git a/vnext/ReactUWP/Base/UwpReactInstance.cpp b/vnext/ReactUWP/Base/UwpReactInstance.cpp index 8fbabcb20ce..ce74a02918b 100644 --- a/vnext/ReactUWP/Base/UwpReactInstance.cpp +++ b/vnext/ReactUWP/Base/UwpReactInstance.cpp @@ -51,7 +51,7 @@ #include "V8JSIRuntimeHolder.h" #endif // USE_V8 -#include +#include #include #include "ChakraRuntimeHolder.h" @@ -87,7 +87,7 @@ struct UwpReactRedBoxHandler : Mso::React::IRedBoxHandler { Microsoft::Common::Unicode::Utf8ToUtf16(ss.str().c_str()), L"RedBox Error"); dlg.ShowAsync(); } - virtual bool isDevSupportEnabled() override { + virtual bool isDevSupportEnabled() const override { return true; } virtual void updateError(Mso::React::ErrorInfo &&) override {} diff --git a/vnext/ReactWindowsCore/DevSettings.h b/vnext/ReactWindowsCore/DevSettings.h index 44808a5e4d9..061ea4259c4 100644 --- a/vnext/ReactWindowsCore/DevSettings.h +++ b/vnext/ReactWindowsCore/DevSettings.h @@ -5,7 +5,7 @@ #include "Logging.h" #include "MemoryTracker.h" -#include +#include #include #include #include diff --git a/vnext/ReactWindowsCore/RedBoxHandler.h b/vnext/ReactWindowsCore/IRedBoxHandler.h similarity index 94% rename from vnext/ReactWindowsCore/RedBoxHandler.h rename to vnext/ReactWindowsCore/IRedBoxHandler.h index aeabb4f9f57..fea578a782b 100644 --- a/vnext/ReactWindowsCore/RedBoxHandler.h +++ b/vnext/ReactWindowsCore/IRedBoxHandler.h @@ -28,7 +28,7 @@ struct ErrorInfo { struct IRedBoxHandler { virtual void showNewError(ErrorInfo &&, ErrorType) = 0; - virtual bool isDevSupportEnabled() = 0; + virtual bool isDevSupportEnabled() const = 0; virtual void updateError(ErrorInfo &&) = 0; virtual void dismissRedbox() = 0; }; diff --git a/vnext/ReactWindowsCore/Modules/ExceptionsManagerModule.h b/vnext/ReactWindowsCore/Modules/ExceptionsManagerModule.h index be44080f41e..80f314a5918 100644 --- a/vnext/ReactWindowsCore/Modules/ExceptionsManagerModule.h +++ b/vnext/ReactWindowsCore/Modules/ExceptionsManagerModule.h @@ -4,7 +4,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems b/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems index 45f57133a2e..0380d8cc221 100644 --- a/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems +++ b/vnext/ReactWindowsCore/ReactWindowsCore.vcxitems @@ -168,7 +168,7 @@ - + diff --git a/vnext/ReactWindowsCore/ReactWindowsCore.vcxproj.filters b/vnext/ReactWindowsCore/ReactWindowsCore.vcxproj.filters index 7db04cf3419..4c1a4081cd6 100644 --- a/vnext/ReactWindowsCore/ReactWindowsCore.vcxproj.filters +++ b/vnext/ReactWindowsCore/ReactWindowsCore.vcxproj.filters @@ -239,7 +239,7 @@ Header Files\Pch - + Header Files diff --git a/vnext/Scripts/ReactWin32.nuspec b/vnext/Scripts/ReactWin32.nuspec index a61bbe5631d..c54093c805e 100644 --- a/vnext/Scripts/ReactWin32.nuspec +++ b/vnext/Scripts/ReactWin32.nuspec @@ -34,7 +34,7 @@ - + From a15b3bfac7ebc29d3a9b642ab5235609b3b1a936 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 13:41:32 -0700 Subject: [PATCH 08/33] Bump fp-ts from 2.5.4 to 2.6.0 (#4871) Bumps [fp-ts](https://github.com/gcanti/fp-ts) from 2.5.4 to 2.6.0. - [Release notes](https://github.com/gcanti/fp-ts/releases) - [Changelog](https://github.com/gcanti/fp-ts/blob/master/CHANGELOG.md) - [Commits](https://github.com/gcanti/fp-ts/compare/2.5.4...2.6.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8dccb129849..5c28f727177 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6999,9 +6999,9 @@ forwarded@~0.1.2: integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fp-ts@^2.5.0: - version "2.5.4" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.5.4.tgz#f184079aaa78403ea66458517be7787e0d593429" - integrity sha512-cZlLeEneRYypc2dOzB9h8+bd9mQhJVyt2g0Dny2gKR7uWNgA4EmLSJyguLYsTU44nJSSG9EjurUalEc0wQqeKw== + version "2.6.0" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.6.0.tgz#55dc9e82612a44a7bfed3484b18c535514d63e51" + integrity sha512-4EKVa3EOP3NoDwXCLgSCT2t+E2wPCWDXCuj3wEcQ1ovkLfdCMxKxCuElpXptIPBmtA+KbjnUl5Ta/1U3jsCmkg== fragment-cache@^0.2.1: version "0.2.1" From e596d14d5f7b9934543469a04ee8d20ba3785a93 Mon Sep 17 00:00:00 2001 From: React-Native-Windows Bot <53619745+rnbot@users.noreply.github.com> Date: Tue, 12 May 2020 00:04:39 +0000 Subject: [PATCH 09/33] applying package updates ***NO_CI*** --- ...ndows-2020-04-29-15-37-41-imageonload.json | 9 -------- ...020-05-04-12-54-41-publiccustomredbox.json | 8 ------- packages/E2ETest/package.json | 2 +- .../package.json | 2 +- packages/playground/package.json | 2 +- vnext/CHANGELOG.json | 21 +++++++++++++++++++ vnext/CHANGELOG.md | 11 +++++++++- vnext/package.json | 2 +- 8 files changed, 35 insertions(+), 22 deletions(-) delete mode 100644 change/react-native-windows-2020-04-29-15-37-41-imageonload.json delete mode 100644 change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json diff --git a/change/react-native-windows-2020-04-29-15-37-41-imageonload.json b/change/react-native-windows-2020-04-29-15-37-41-imageonload.json deleted file mode 100644 index 714ebefda8d..00000000000 --- a/change/react-native-windows-2020-04-29-15-37-41-imageonload.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "prerelease", - "comment": "Fire onLoad event when a bitmap image is opeed", - "packageName": "react-native-windows", - "email": "lamdoan@microsoft.com", - "commit": "22edad7ea69232ae7636424c237df4eee7577f54", - "dependentChangeType": "patch", - "date": "2020-04-29T22:37:41.642Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json b/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json deleted file mode 100644 index dc9e8030a2f..00000000000 --- a/change/react-native-windows-2020-05-04-12-54-41-publiccustomredbox.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Expose ability for apps to provide their own RedBox implementation", - "packageName": "react-native-windows", - "email": "acoates@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-05-04T19:54:41.414Z" -} diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json index 39106f4510a..a2448e2e4ba 100644 --- a/packages/E2ETest/package.json +++ b/packages/E2ETest/package.json @@ -25,7 +25,7 @@ "prompt-sync": "^4.2.0", "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.63" + "react-native-windows": "0.0.0-master.64" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/microsoft-reactnative-sampleapps/package.json b/packages/microsoft-reactnative-sampleapps/package.json index faf33dc0167..a994357bb72 100644 --- a/packages/microsoft-reactnative-sampleapps/package.json +++ b/packages/microsoft-reactnative-sampleapps/package.json @@ -16,7 +16,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.63" + "react-native-windows": "0.0.0-master.64" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/playground/package.json b/packages/playground/package.json index 449e7089930..55d1d381182 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,7 +11,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.63" + "react-native-windows": "0.0.0-master.64" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json index f1ddb330210..a53ac0d9280 100644 --- a/vnext/CHANGELOG.json +++ b/vnext/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "react-native-windows", "entries": [ + { + "date": "Tue, 12 May 2020 00:04:39 GMT", + "tag": "react-native-windows_v0.0.0-master.64", + "version": "0.0.0-master.64", + "comments": { + "prerelease": [ + { + "comment": "Fire onLoad event when a bitmap image is opeed", + "author": "lamdoan@microsoft.com", + "commit": "c40cc0ea1de8b4acb830939ba79146739f438111", + "package": "react-native-windows" + }, + { + "comment": "Expose ability for apps to provide their own RedBox implementation", + "author": "acoates@microsoft.com", + "commit": "55091b9447d741fc0e9c23acb8dfdee53ad11598", + "package": "react-native-windows" + } + ] + } + }, { "date": "Sun, 10 May 2020 00:05:02 GMT", "tag": "react-native-windows_v0.0.0-master.63", diff --git a/vnext/CHANGELOG.md b/vnext/CHANGELOG.md index c340b96fa98..b680713a308 100644 --- a/vnext/CHANGELOG.md +++ b/vnext/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - react-native-windows -This log was last generated on Sun, 10 May 2020 00:05:02 GMT and should not be manually modified. +This log was last generated on Tue, 12 May 2020 00:04:39 GMT and should not be manually modified. +## 0.0.0-master.64 + +Tue, 12 May 2020 00:04:39 GMT + +### Changes + +- Fire onLoad event when a bitmap image is opeed (lamdoan@microsoft.com) +- Expose ability for apps to provide their own RedBox implementation (acoates@microsoft.com) + ## 0.0.0-master.63 Sun, 10 May 2020 00:05:02 GMT diff --git a/vnext/package.json b/vnext/package.json index c3e32b9805b..228a39cb384 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.0.0-master.63", + "version": "0.0.0-master.64", "license": "MIT", "repository": { "type": "git", From d5e8bdcbf63a8ee2e9221bfa344faa227ef892e3 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Mon, 11 May 2020 17:52:18 -0700 Subject: [PATCH 10/33] Fixed ReactContext copy/move semantic (#4870) * Fixed ReactContext copy/move semantic * Change files * Fixed formatting * Test to show how to use a delegate in ReactPropertyBag --- ...s-2020-05-11-11-06-42-FixReactContext.json | 8 ++ ...icrosoft.ReactNative.Cxx.UnitTests.vcxproj | 1 + .../ReactContextTest.cpp | 113 ++++++++++++++++++ .../Microsoft.ReactNative.Cxx/JSValueWriter.h | 3 +- .../Microsoft.ReactNative.Cxx/ReactContext.h | 28 ++++- .../ReactNativeHostTests.cpp | 2 + .../ReactPropertyBagTests.cpp | 20 +++- .../pch.h | 1 - 8 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json create mode 100644 vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactContextTest.cpp diff --git a/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json b/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json new file mode 100644 index 00000000000..d3bc77290fd --- /dev/null +++ b/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Fixed ReactContext copy/move semantic", + "packageName": "react-native-windows", + "email": "vmorozov@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-11T18:06:42.425Z" +} diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj index 1849911ed19..79d66fa1e3a 100644 --- a/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj @@ -126,6 +126,7 @@ Create + diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactContextTest.cpp b/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactContextTest.cpp new file mode 100644 index 00000000000..c2d28914c93 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactContextTest.cpp @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" +#include +#include "ReactModuleBuilderMock.h" + +using namespace winrt::Microsoft::ReactNative; + +struct ReactContextStub : implements { + IReactPropertyBag Properties() noexcept { + VerifyElseCrashSz(false, "Not implemented"); + } + + void DispatchEvent( + xaml::FrameworkElement const & /*view*/, + hstring const & /*eventName*/, + JSValueArgWriter const & /*eventDataArgWriter*/) noexcept { + VerifyElseCrashSz(false, "Not implemented"); + } + + void CallJSFunction( + hstring const & /*moduleName*/, + hstring const & /*functionName*/, + JSValueArgWriter const & /*paramsArgWriter*/) noexcept { + VerifyElseCrashSz(false, "Not implemented"); + } + + void EmitJSEvent( + hstring const & /*eventEmitterName*/, + hstring const & /*eventName*/, + JSValueArgWriter const & /*paramsArgWriter*/) noexcept { + VerifyElseCrashSz(false, "Not implemented"); + } +}; + +namespace ReactNativeTests { + +TEST_CLASS (ReactContextTest) { + TEST_METHOD(Test_ctor_Default) { + ReactContext context; + TestCheck(!context); + } + + TEST_METHOD(Test_ctor_IReactContext) { + auto reactContextMock = winrt::make(); + ReactContext context{reactContextMock}; + TestCheck(context); + } + + TEST_METHOD(Test_ctor_copy) { + auto reactContextMock = winrt::make(); + ReactContext context1{reactContextMock}; + ReactContext context2{context1}; + TestCheck(context1); + TestCheck(context2); + TestCheckEqual(context1, context2); + } + + TEST_METHOD(Test_ctor_move) { + auto reactContextMock = winrt::make(); + ReactContext context1{reactContextMock}; + ReactContext context2{std::move(context1)}; + TestCheck(!context1); + TestCheck(context2); + } + + TEST_METHOD(Test_assign_nullptr) { + ReactContext context; + context = nullptr; + TestCheck(!context); + } + + TEST_METHOD(Test_assign_copy) { + auto reactContextMock = winrt::make(); + ReactContext context1{reactContextMock}; + ReactContext context2; + context2 = context1; + TestCheck(context1); + TestCheck(context2); + TestCheckEqual(context1, context2); + } + + TEST_METHOD(Test_assign_move) { + auto reactContextMock = winrt::make(); + ReactContext context1{reactContextMock}; + ReactContext context2; + context2 = std::move(context1); + TestCheck(!context1); + TestCheck(context2); + } + + TEST_METHOD(Test_compare) { + auto reactContextMock1 = winrt::make(); + auto reactContextMock2 = winrt::make(); + ReactContext context11{reactContextMock1}; + ReactContext context12{context11}; + ReactContext context2{reactContextMock2}; + ReactContext context3; + TestCheck(context11 == context12); + TestCheck(context12 == context11); + TestCheck(context11 != context2); + TestCheck(context11 != context3); + TestCheck(context2 != context11); + TestCheck(context3 != context11); + TestCheck(context3 == nullptr); + TestCheck(nullptr == context3); + TestCheck(context11 != nullptr); + TestCheck(nullptr != context11); + } +}; + +} // namespace ReactNativeTests diff --git a/vnext/Microsoft.ReactNative.Cxx/JSValueWriter.h b/vnext/Microsoft.ReactNative.Cxx/JSValueWriter.h index 547ac7ead65..80b6cb68748 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSValueWriter.h +++ b/vnext/Microsoft.ReactNative.Cxx/JSValueWriter.h @@ -5,8 +5,9 @@ #ifndef MICROSOFT_REACTNATIVE_JSVALUEWRITER #define MICROSOFT_REACTNATIVE_JSVALUEWRITER +#include +#include "JSValue.h" #include "StructInfo.h" -#include "winrt/Microsoft.ReactNative.h" namespace winrt::Microsoft::ReactNative { diff --git a/vnext/Microsoft.ReactNative.Cxx/ReactContext.h b/vnext/Microsoft.ReactNative.Cxx/ReactContext.h index a40c869f3c6..3dc09ee14ad 100644 --- a/vnext/Microsoft.ReactNative.Cxx/ReactContext.h +++ b/vnext/Microsoft.ReactNative.Cxx/ReactContext.h @@ -16,6 +16,8 @@ namespace winrt::Microsoft::ReactNative { // It wraps up the IReactContext and adds convenience methods for // working with C++ types. struct ReactContext { + ReactContext(std::nullptr_t = nullptr) noexcept {} + ReactContext(IReactContext const &handle) noexcept : m_handle{handle} {} IReactContext const &Handle() const noexcept { @@ -66,8 +68,32 @@ struct ReactContext { m_handle.DispatchEvent(view, eventName, paramsArgWriter); } + friend bool operator==(ReactContext const &left, ReactContext const &right) noexcept { + return left.m_handle == right.m_handle; + } + + friend bool operator!=(ReactContext const &left, ReactContext const &right) noexcept { + return left.m_handle != right.m_handle; + } + + friend bool operator==(ReactContext const &left, std::nullptr_t) noexcept { + return !static_cast(left.m_handle); + } + + friend bool operator!=(ReactContext const &left, std::nullptr_t) noexcept { + return static_cast(left.m_handle); + } + + friend bool operator==(std::nullptr_t, ReactContext const &right) noexcept { + return !static_cast(right.m_handle); + } + + friend bool operator!=(std::nullptr_t, ReactContext const &right) noexcept { + return static_cast(right.m_handle); + } + private: - const IReactContext m_handle; + IReactContext m_handle; }; } // namespace winrt::Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/ReactNativeHostTests.cpp b/vnext/Microsoft.ReactNative.IntegrationTests/ReactNativeHostTests.cpp index 11d16009c32..2f11c1d9291 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/ReactNativeHostTests.cpp +++ b/vnext/Microsoft.ReactNative.IntegrationTests/ReactNativeHostTests.cpp @@ -1,5 +1,7 @@ #include "pch.h" +#include + using namespace React; namespace ReactNativeIntegrationTests { diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp b/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp index 7553d4be66a..27168257d81 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp +++ b/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp @@ -491,7 +491,6 @@ TEST_CLASS (ReactPropertyBagTests) { } TEST_METHOD(PropertyBag_Property_string) { - // We only support enums defined in IDL. ReactPropertyId fooName{L"Foo"}; ReactPropertyBag pb{ReactPropertyBagHelper::CreatePropertyBag()}; @@ -504,6 +503,25 @@ TEST_CLASS (ReactPropertyBagTests) { pb.Remove(fooName); TestCheck(!pb.Get(fooName)); } + + TEST_METHOD(PropertyBag_Property_delegate) { + ReactPropertyId fooName{L"Foo"}; + ReactPropertyBag pb{ReactPropertyBagHelper::CreatePropertyBag()}; + + TestCheck(!pb.Get(fooName)); + ReactCreatePropertyValue createValue1 = []() { return winrt::box_value(5); }; + TestCheckEqual(createValue1, *pb.GetOrCreate(fooName, [&createValue1]() { return createValue1; })); + TestCheckEqual(createValue1, *pb.Get(fooName)); + TestCheckEqual(5, winrt::unbox_value((*pb.Get(fooName))())); + + ReactCreatePropertyValue createValue2 = []() { return winrt::box_value(10); }; + pb.Set(fooName, createValue2); + TestCheckEqual(createValue2, *pb.Get(fooName)); + TestCheckEqual(10, winrt::unbox_value((*pb.Get(fooName))())); + TestCheck(createValue1 != *pb.Get(fooName)); + pb.Remove(fooName); + TestCheck(!pb.Get(fooName)); + } }; } // namespace ReactNativeIntegrationTests diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/pch.h b/vnext/Microsoft.ReactNative.IntegrationTests/pch.h index cde08a53662..19f70f55b7b 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/pch.h +++ b/vnext/Microsoft.ReactNative.IntegrationTests/pch.h @@ -3,7 +3,6 @@ #define NOMINMAX #include -#include "NativeModules.h" #include "functional/functor.h" #include "motifCpp/testCheck.h" From 49e65479d70ab1df738cb7bf21e915e9453eaf13 Mon Sep 17 00:00:00 2001 From: Andreas Eulitz <44379427+aeulitz@users.noreply.github.com> Date: Mon, 11 May 2020 18:51:34 -0700 Subject: [PATCH 11/33] Add ReactNativeHost to Win32 C++/WinRT ABI (#4848) * create MS.ReactNative.IntegrationTests project * RNHost activation succeeds * update * update * Change files * add JS function call test * Change files * fix formatting * submit current state * ReactNativeHost activation test succeeds * Change files * account for property bag addition * sync, address code review feedback --- ...indows-2020-04-30-18-28-03-abi-safety.json | 8 +++ ...indows-2020-05-09-17-42-52-abi-safety.json | 8 +++ vnext/Desktop.ABITests/ActivationFactory.cpp | 2 +- vnext/Desktop.ABITests/ActivationFactory.h | 10 +++ vnext/Desktop.ABITests/MemoryTrackerTests.cpp | 3 +- .../Desktop.ABITests/NativeLogEventTests.cpp | 3 +- .../NativeTraceEventTests.cpp | 3 +- .../React.Windows.Desktop.ABITests.vcxproj | 5 ++ ...t.Windows.Desktop.ABITests.vcxproj.filters | 6 ++ .../Desktop.ABITests/ReactNativeHostTests.cpp | 29 ++++++++ vnext/Desktop/ABI/ReactNativeHost.cpp | 66 +++++++++++++++++++ vnext/Desktop/ABI/ReactNativeHost.h | 42 ++++++++++++ vnext/Desktop/React.Windows.Desktop.vcxproj | 22 +++++++ .../React.Windows.Desktop.vcxproj.filters | 33 ++++++++++ vnext/Desktop/module.g.cpp | 8 +++ 15 files changed, 241 insertions(+), 7 deletions(-) create mode 100644 change/react-native-windows-2020-04-30-18-28-03-abi-safety.json create mode 100644 change/react-native-windows-2020-05-09-17-42-52-abi-safety.json create mode 100644 vnext/Desktop.ABITests/ActivationFactory.h create mode 100644 vnext/Desktop.ABITests/ReactNativeHostTests.cpp create mode 100644 vnext/Desktop/ABI/ReactNativeHost.cpp create mode 100644 vnext/Desktop/ABI/ReactNativeHost.h diff --git a/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json b/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json new file mode 100644 index 00000000000..7cf31717cd8 --- /dev/null +++ b/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json @@ -0,0 +1,8 @@ +{ + "type": "none", + "comment": "test bundle build logic, JS function call test", + "packageName": "react-native-windows", + "email": "aeulitz@microsoft.com", + "dependentChangeType": "none", + "date": "2020-05-01T01:28:03.315Z" +} diff --git a/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json b/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json new file mode 100644 index 00000000000..ef25becd822 --- /dev/null +++ b/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "add ReactNativeHost to Win32 C++/WinRT ABI", + "packageName": "react-native-windows", + "email": "aeulitz@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-10T00:42:52.866Z" +} diff --git a/vnext/Desktop.ABITests/ActivationFactory.cpp b/vnext/Desktop.ABITests/ActivationFactory.cpp index 81ff78b6cf7..19915c7e683 100644 --- a/vnext/Desktop.ABITests/ActivationFactory.cpp +++ b/vnext/Desktop.ABITests/ActivationFactory.cpp @@ -26,7 +26,7 @@ int32_t __stdcall WINRT_RoGetActivationFactory(void *classId, guid const &iid, v std::wstring_view const name{*reinterpret_cast(&classId)}; HMODULE library{nullptr}; - if (starts_with(name, L"facebook.react.")) { + if (starts_with(name, L"facebook.react.") || starts_with(name, L"Microsoft.React")) { library = LoadLibraryExW(RNDLLPATH, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); } else { return OS_RoGetActivationFactory(classId, iid, factory); diff --git a/vnext/Desktop.ABITests/ActivationFactory.h b/vnext/Desktop.ABITests/ActivationFactory.h new file mode 100644 index 00000000000..e53f76d24ce --- /dev/null +++ b/vnext/Desktop.ABITests/ActivationFactory.h @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "pch.h" +#include +#include + +extern int32_t __stdcall WINRT_RoGetActivationFactory(void *classId, winrt::guid const &iid, void **factory) noexcept; diff --git a/vnext/Desktop.ABITests/MemoryTrackerTests.cpp b/vnext/Desktop.ABITests/MemoryTrackerTests.cpp index ce3da0f7549..79ad888716c 100644 --- a/vnext/Desktop.ABITests/MemoryTrackerTests.cpp +++ b/vnext/Desktop.ABITests/MemoryTrackerTests.cpp @@ -7,14 +7,13 @@ #include #include +#include "ActivationFactory.h" #include "MessageQueueShim.h" using namespace Microsoft::React::Test; using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace winrt::facebook::react; -int32_t __stdcall WINRT_RoGetActivationFactory(void *classId, winrt::guid const &iid, void **factory) noexcept; - namespace ABITests { // We turn clang format off here because it does not work with some of the diff --git a/vnext/Desktop.ABITests/NativeLogEventTests.cpp b/vnext/Desktop.ABITests/NativeLogEventTests.cpp index d23fd4ae2ad..859b84dca56 100644 --- a/vnext/Desktop.ABITests/NativeLogEventTests.cpp +++ b/vnext/Desktop.ABITests/NativeLogEventTests.cpp @@ -5,13 +5,12 @@ #include #include #include +#include "ActivationFactory.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace winrt::facebook::react; using namespace winrt; -int32_t __stdcall WINRT_RoGetActivationFactory(void *classId, winrt::guid const &iid, void **factory) noexcept; - namespace ABITests { TEST_CLASS (NativeLogEventTests) { diff --git a/vnext/Desktop.ABITests/NativeTraceEventTests.cpp b/vnext/Desktop.ABITests/NativeTraceEventTests.cpp index 371589c30a1..16348920fa3 100644 --- a/vnext/Desktop.ABITests/NativeTraceEventTests.cpp +++ b/vnext/Desktop.ABITests/NativeTraceEventTests.cpp @@ -6,13 +6,12 @@ #include #include #include +#include "ActivationFactory.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace winrt::facebook::react; using namespace winrt; -int32_t __stdcall WINRT_RoGetActivationFactory(void *classId, winrt::guid const &iid, void **factory) noexcept; - namespace ABITests { TEST_CLASS (NativeTraceEventTests) { diff --git a/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj b/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj index ec0af2a58ba..c4972ba5924 100644 --- a/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj +++ b/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj @@ -103,6 +103,9 @@ $(OutputPath)..\React.Windows.Desktop\facebook.react.winmd + + $(OutputPath)..\React.Windows.Desktop\Microsoft.ReactNative.winmd + @@ -133,9 +136,11 @@ Create + + diff --git a/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj.filters b/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj.filters index 49daa4eb2a2..76bd4b11819 100644 --- a/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj.filters +++ b/vnext/Desktop.ABITests/React.Windows.Desktop.ABITests.vcxproj.filters @@ -36,6 +36,9 @@ Source Files + + Source Files + @@ -44,6 +47,9 @@ Header Files + + Header Files + diff --git a/vnext/Desktop.ABITests/ReactNativeHostTests.cpp b/vnext/Desktop.ABITests/ReactNativeHostTests.cpp new file mode 100644 index 00000000000..7206f5b8daf --- /dev/null +++ b/vnext/Desktop.ABITests/ReactNativeHostTests.cpp @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" +#include +#include +#include "ActivationFactory.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace ABITests { + +TEST_CLASS (ReactNativeHostTests) { + public: + ReactNativeHostTests() noexcept { + winrt_activation_handler = WINRT_RoGetActivationFactory; + } + + TEST_METHOD(Activation_Succeeds) { + try { + winrt::Microsoft::ReactNative::ReactNativeHost host{}; + Assert::IsTrue(true); + } catch (...) { + Assert::Fail(); + } + } +}; + +} // namespace ABITests diff --git a/vnext/Desktop/ABI/ReactNativeHost.cpp b/vnext/Desktop/ABI/ReactNativeHost.cpp new file mode 100644 index 00000000000..4486d9a209f --- /dev/null +++ b/vnext/Desktop/ABI/ReactNativeHost.cpp @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include +#include "ReactNativeHost.h" + +#include "Microsoft.ReactNative.ReactNativeHost.g.cpp" + +using namespace winrt::Windows::Foundation::Collections; + +namespace winrt::Microsoft::ReactNative::implementation { + +ReactNativeHost::ReactNativeHost() noexcept { + // TODO: implement +} + +IVector ReactNativeHost::PackageProviders() noexcept { + if (!m_packageProviders) { + m_packageProviders = single_threaded_vector(); + } + + return m_packageProviders; +} + +void ReactNativeHost::PackageProviders(IVector const &value) noexcept { + m_packageProviders = value; +} + +ReactNative::ReactInstanceSettings ReactNativeHost::InstanceSettings() noexcept { + if (!m_instanceSettings) { + // TODO: implement + // m_instanceSettings = make(); + } + + return m_instanceSettings; +} + +void ReactNativeHost::InstanceSettings(ReactNative::ReactInstanceSettings const &value) noexcept { + m_instanceSettings = value; +} + +void ReactNativeHost::ReloadInstance() noexcept { + // TODO: implement +} + +void ReactNativeHost::OnSuspend() noexcept { + // TODO: implement +} + +void ReactNativeHost::OnEnteredBackground() noexcept { + // TODO: implement +} + +void ReactNativeHost::OnLeavingBackground() noexcept { + // TODO: implement +} + +void ReactNativeHost::OnResume(OnResumeAction const & /*action*/) noexcept { + // TODO: implement +} + +void ReactNativeHost::OnBackPressed() noexcept { + // TODO: implement +} + +} // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Desktop/ABI/ReactNativeHost.h b/vnext/Desktop/ABI/ReactNativeHost.h new file mode 100644 index 00000000000..f1596c4b49b --- /dev/null +++ b/vnext/Desktop/ABI/ReactNativeHost.h @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include + +#include "Microsoft.ReactNative.ReactNativeHost.g.h" + +namespace winrt::Microsoft::ReactNative::implementation { + +struct ReactNativeHost : ReactNativeHostT { + ReactNativeHost() noexcept; + + // property PackageProviders + Windows::Foundation::Collections::IVector PackageProviders() noexcept; + void PackageProviders(Windows::Foundation::Collections::IVector const &value) noexcept; + + // property InstanceSettings + ReactNative::ReactInstanceSettings InstanceSettings() noexcept; + void InstanceSettings(ReactNative::ReactInstanceSettings const &value) noexcept; + + void ReloadInstance() noexcept; + + void OnSuspend() noexcept; + void OnEnteredBackground() noexcept; + void OnLeavingBackground() noexcept; + void OnResume(OnResumeAction const &action) noexcept; + void OnBackPressed() noexcept; + + private: + ReactNative::ReactInstanceSettings m_instanceSettings{nullptr}; + Windows::Foundation::Collections::IVector m_packageProviders; +}; + +} // namespace winrt::Microsoft::ReactNative::implementation + +namespace winrt::Microsoft::ReactNative::factory_implementation { + +struct ReactNativeHost : ReactNativeHostT {}; + +} // namespace winrt::Microsoft::ReactNative::factory_implementation diff --git a/vnext/Desktop/React.Windows.Desktop.vcxproj b/vnext/Desktop/React.Windows.Desktop.vcxproj index 556cb33f4db..304f44e661b 100644 --- a/vnext/Desktop/React.Windows.Desktop.vcxproj +++ b/vnext/Desktop/React.Windows.Desktop.vcxproj @@ -90,6 +90,9 @@ Shlwapi.lib;%(AdditionalDependencies) -minpdbpathlen:256 + + $(ReactNativeWindowsDir)\Microsoft.ReactNative;$(ReactNativeWindowsDir)\Microsoft.ReactNative.Cxx; + @@ -97,6 +100,17 @@ + + + + + + + + + + + @@ -115,6 +129,10 @@ ABI\NativeTracing.idl $(IntDir)\ABI\ + + ..\Microsoft.ReactNative\ReactNativeHost.idl + $(IntDir)\ABI\ + @@ -145,6 +163,10 @@ ABI\NativeTracing.idl + + ..\Microsoft.ReactNative\ReactNativeHost.idl + Code + diff --git a/vnext/Desktop/React.Windows.Desktop.vcxproj.filters b/vnext/Desktop/React.Windows.Desktop.vcxproj.filters index e150e18d4fa..6a4be8c5886 100644 --- a/vnext/Desktop/React.Windows.Desktop.vcxproj.filters +++ b/vnext/Desktop/React.Windows.Desktop.vcxproj.filters @@ -42,6 +42,39 @@ ABI + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + + + ABI + diff --git a/vnext/Desktop/module.g.cpp b/vnext/Desktop/module.g.cpp index 84d71805b03..a1ed4613ebe 100644 --- a/vnext/Desktop/module.g.cpp +++ b/vnext/Desktop/module.g.cpp @@ -1,8 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// WARNING: Please don't edit this file. It was generated by C++/WinRT v2.0.200316.3 + #include "pch.h" #include "winrt/base.h" +void* winrt_make_Microsoft_ReactNative_ReactNativeHost(); void* winrt_make_facebook_react_MemoryTracker(); void* winrt_make_facebook_react_NativeLogEventSource(); void* winrt_make_facebook_react_NativeTraceEventSource(); @@ -25,6 +28,11 @@ void* __stdcall winrt_get_activation_factory([[maybe_unused]] std::wstring_view return std::equal(left.rbegin(), left.rend(), right.rbegin(), right.rend()); }; + if (requal(name, L"Microsoft.ReactNative.ReactNativeHost")) + { + return winrt_make_Microsoft_ReactNative_ReactNativeHost(); + } + if (requal(name, L"facebook.react.MemoryTracker")) { return winrt_make_facebook_react_MemoryTracker(); From 8033b548f81e48d904b4dd1b1f81df33dbb232c4 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Tue, 12 May 2020 14:41:11 -0700 Subject: [PATCH 12/33] Use spec file for DevSettings NativeModule (#4873) * Use spec file for DevSettings NativeModule * Change files * minor change --- ...s-2020-05-11-13-26-08-devsettingsspec.json | 8 +++ .../Modules/DevSettingsModule.cpp | 69 +++++++++++-------- .../Modules/DevSettingsModule.h | 36 +++++----- .../ReactHost/ReactInstanceWin.cpp | 25 ++++--- 4 files changed, 81 insertions(+), 57 deletions(-) create mode 100644 change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json diff --git a/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json b/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json new file mode 100644 index 00000000000..bf2f07e8b92 --- /dev/null +++ b/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Use spec file for DevSettings NativeModule", + "packageName": "react-native-windows", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-11T20:26:08.523Z" +} diff --git a/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.cpp b/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.cpp index 6d4312211c7..90a86c23900 100644 --- a/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.cpp @@ -6,53 +6,66 @@ namespace Microsoft::ReactNative { -auto DevSettingsModule::getConstants() -> std::map { - return {}; +void DevSettings::Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept { + m_context = reactContext; } -const char *DevSettingsModule::name = "DevSettings"; -std::string DevSettingsModule::getName() { - return name; +struct ReloadFunctor + : winrt::implements> { + ReloadFunctor(Mso::VoidFunctor &&func) : m_func(std::move(func)) {} + + void operator()() { + m_func(); + } + + private: + Mso::VoidFunctor m_func; +}; + +/*static*/ void DevSettings::SetReload(Mso::React::ReactOptions const &options, Mso::VoidFunctor &&func) noexcept { + options.Properties.Set(ReloadProperty(), winrt::make(std::move(func))); } -DevSettingsModule::DevSettingsModule(Mso::VoidFunctor &&reload) : m_reload(std::move(reload)) {} +/*static*/ winrt::Microsoft::ReactNative::IReactPropertyName DevSettings::ReloadProperty() noexcept { + return winrt::Microsoft::ReactNative::ReactPropertyBagHelper::GetName( + winrt::Microsoft::ReactNative::ReactPropertyBagHelper::GetNamespace(L"DevSettings"), L"Reload"); +} -void DevSettingsModule::reload() { - m_reload(); +void DevSettings::reload() noexcept { + (*winrt::get_self(m_context.Properties().Get( + winrt::Microsoft::ReactNative::ReactPropertyId(ReloadProperty()))))(); } -void DevSettingsModule::setHotLoadingEnabled(bool /*isHotLoadingEnabled*/) { - assert(false); + +void DevSettings::reloadWithReason(std::string /*reason*/) noexcept { + reload(); } -void DevSettingsModule::setIsDebuggingRemotely(bool /*isDebuggingRemotelyEnabled*/) { + +void DevSettings::onFastRefresh() noexcept { + // noop +} + +void DevSettings::setHotLoadingEnabled(bool isHotLoadingEnabled) noexcept { assert(false); } -void DevSettingsModule::setLiveReloadEnabled(bool /*setLiveReloadEnabled*/) { + +void DevSettings::setIsDebuggingRemotely(bool isDebuggingRemotelyEnabled) noexcept { assert(false); } -void DevSettingsModule::setProfilingEnabled(bool /*setProfilingEnabled*/) { + +void DevSettings::setProfilingEnabled(bool isProfilingEnabled) noexcept { assert(false); } -void DevSettingsModule::toggleElementInspector() { + +void DevSettings::toggleElementInspector() noexcept { assert(false); } -// iOS only. -void DevSettingsModule::setIsShakeToShowDevMenuEnabled(bool /*enabled*/) { +void DevSettings::addMenuItem(std::string title) noexcept { assert(false); } -auto DevSettingsModule::getMethods() -> std::vector { - return { - Method("reload", [this](folly::dynamic args) { reload(); }), - Method("setHotLoadingEnabled", [this](folly::dynamic args) { setHotLoadingEnabled(args[0].getBool()); }), - Method("setIsDebuggingRemotely", [this](folly::dynamic args) { setIsDebuggingRemotely(args[0].getBool()); }), - Method("setLiveReloadEnabled", [this](folly::dynamic args) { setLiveReloadEnabled(args[0].getBool()); }), - Method("setProfilingEnabled", [this](folly::dynamic args) { setProfilingEnabled(args[0].getBool()); }), - Method("toggleElementInspector", [this](folly::dynamic args) { toggleElementInspector(); }), - Method( - "setIsShakeToShowDevMenuEnabled", - [this](folly::dynamic args) { setIsShakeToShowDevMenuEnabled(args[0].getBool()); }), - }; +void DevSettings::setIsShakeToShowDevMenuEnabled(bool enabled) noexcept { + assert(false); } } // namespace Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.h b/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.h index 531aec8024a..aeddf6a7c3d 100644 --- a/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.h +++ b/vnext/Microsoft.ReactNative/Modules/DevSettingsModule.h @@ -5,30 +5,30 @@ #include #include -namespace Microsoft::ReactNative { - -class DevSettingsModule : public facebook::xplat::module::CxxModule { - public: - DevSettingsModule(Mso::VoidFunctor &&reload); +#include +#include - static const char *name; +namespace Microsoft::ReactNative { - std::string getName() override; - std::map getConstants() override; - std::vector getMethods() override; +REACT_MODULE(DevSettings) +struct DevSettings { + REACT_INIT(Initialize) void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept; - void reload(); - void setHotLoadingEnabled(bool isHotLoadingEnabled); - void setIsDebuggingRemotely(bool isDebuggingRemotelyEnabled); - void setLiveReloadEnabled(bool setLiveReloadEnabled); - void setProfilingEnabled(bool setProfilingEnabled); - void toggleElementInspector(); + REACT_METHOD(reload) void reload() noexcept; + REACT_METHOD(reloadWithReason) void reloadWithReason(std::string reason) noexcept; + REACT_METHOD(onFastRefresh) void onFastRefresh() noexcept; + REACT_METHOD(setHotLoadingEnabled) void setHotLoadingEnabled(bool isHotLoadingEnabled) noexcept; + REACT_METHOD(setIsDebuggingRemotely) void setIsDebuggingRemotely(bool isDebuggingRemotelyEnabled) noexcept; + REACT_METHOD(setProfilingEnabled) void setProfilingEnabled(bool isProfilingEnabled) noexcept; + REACT_METHOD(toggleElementInspector) void toggleElementInspector() noexcept; + REACT_METHOD(addMenuItem) void addMenuItem(std::string title) noexcept; + REACT_METHOD(setIsShakeToShowDevMenuEnabled) void setIsShakeToShowDevMenuEnabled(bool enabled) noexcept; - // iOS only. - void setIsShakeToShowDevMenuEnabled(bool enabled); + static void SetReload(Mso::React::ReactOptions const &options, Mso::VoidFunctor &&func) noexcept; private: - Mso::VoidFunctor m_reload; + static winrt::Microsoft::ReactNative::IReactPropertyName ReloadProperty() noexcept; + winrt::Microsoft::ReactNative::ReactContext m_context; }; } // namespace Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp index 0218b9b075c..d5e8e48bba8 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +++ b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp @@ -14,6 +14,7 @@ #include "Microsoft.ReactNative/Threading/MessageQueueThreadFactory.h" #include "../../codegen/NativeClipboardSpec.g.h" +#include "../../codegen/NativeDevSettingsSpec.g.h" #include "NativeModules.h" #include "NativeModulesProvider.h" #include "Unicode.h" @@ -218,21 +219,23 @@ void ReactInstanceWin::Initialize() noexcept { ::Microsoft::ReactNative::Clipboard, ::Microsoft::ReactNativeSpecs::ClipboardSpec>()); + ::Microsoft::ReactNative::DevSettings::SetReload( + strongThis->Options(), [weakReactHost = m_weakReactHost]() noexcept { + if (auto reactHost = weakReactHost.GetStrongPtr()) { + reactHost->ReloadInstance(); + } + }); + + nmp->AddModuleProvider( + L"DevSettings", + winrt::Microsoft::ReactNative::MakeTurboModuleProvider< + ::Microsoft::ReactNative::DevSettings, + ::Microsoft::ReactNativeSpecs::DevSettingsSpec>()); + auto modules = nmp->GetModules(m_reactContext, m_batchingUIThread); cxxModules.insert( cxxModules.end(), std::make_move_iterator(modules.begin()), std::make_move_iterator(modules.end())); - cxxModules.emplace_back( - Microsoft::ReactNative::DevSettingsModule::name, - [weakReactHost = strongThis->m_weakReactHost]() { - return std::make_unique([weakReactHost]() noexcept { - if (auto reactHost = weakReactHost.GetStrongPtr()) { - reactHost->ReloadInstance(); - } - }); - }, - m_batchingUIThread); - if (m_options.ModuleProvider != nullptr) { std::vector customCxxModules = m_options.ModuleProvider->GetModules(m_reactContext, m_batchingUIThread); From dbe875f5f1445d4a3967b466ad83d0c33d76a53c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Rocha?= Date: Tue, 12 May 2020 15:09:12 -0700 Subject: [PATCH 13/33] Handle HTTP errors in DevSupportManager. (#4880) * Handle HTTP connect exceptions in DevSupportManager * Change files --- ...2020-05-12-14-18-36-OC-4094136-connectxcpt.json | 8 ++++++++ vnext/Desktop/DevSupportManager.cpp | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json diff --git a/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json b/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json new file mode 100644 index 00000000000..6d5da5b4ecf --- /dev/null +++ b/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json @@ -0,0 +1,8 @@ +{ + "type": "none", + "comment": "Handle HTTP connect exceptions in DevSupportManager", + "packageName": "react-native-windows", + "email": "julio.rocha@microsoft.com", + "dependentChangeType": "none", + "date": "2020-05-12T21:18:36.538Z" +} diff --git a/vnext/Desktop/DevSupportManager.cpp b/vnext/Desktop/DevSupportManager.cpp index d5c8d5c7dba..2877c043fa2 100644 --- a/vnext/Desktop/DevSupportManager.cpp +++ b/vnext/Desktop/DevSupportManager.cpp @@ -59,7 +59,12 @@ string DevSupportManager::GetJavaScriptFromServer( Url url(bundleUrl); auto const resolveResult = m_resolver.resolve(url.host, url.port); tcp::socket socket{m_context}; - connect(socket, resolveResult); + boost::system::error_code ec; + connect(socket, resolveResult, ec); + if (ec) { + m_exceptionCaught = true; + return R"({"error:")"s + ec.message() + R"("})"s; + } request request{verb::get, url.Target(), 11}; request.set(field::host, url.host); @@ -119,7 +124,12 @@ task DevSupportManager::LaunchDevToolsAsync(const string &debugHost, const Url url(DevServerHelper::get_LaunchDevToolsCommandUrl(debugHost)); auto const resolveResult = m_resolver.resolve(url.host, url.port); tcp::socket socket{m_context}; - connect(socket, resolveResult); + boost::system::error_code ec; + connect(socket, resolveResult, ec); + if (ec) { + m_exceptionCaught = true; + return; + } request request{verb::get, url.Target(), 11}; request.set(field::host, url.host); From be556508b69e022ce99ea0475ee354962d8e200c Mon Sep 17 00:00:00 2001 From: React-Native-Windows Bot <53619745+rnbot@users.noreply.github.com> Date: Wed, 13 May 2020 00:04:21 +0000 Subject: [PATCH 14/33] applying package updates ***NO_CI*** --- ...indows-2020-04-30-18-28-03-abi-safety.json | 8 ---- ...indows-2020-05-09-17-42-52-abi-safety.json | 8 ---- ...s-2020-05-11-11-06-42-FixReactContext.json | 8 ---- ...s-2020-05-11-13-26-08-devsettingsspec.json | 8 ---- ...05-12-14-18-36-OC-4094136-connectxcpt.json | 8 ---- packages/E2ETest/package.json | 2 +- .../package.json | 2 +- packages/playground/package.json | 2 +- vnext/CHANGELOG.json | 41 +++++++++++++++++++ vnext/CHANGELOG.md | 12 +++++- vnext/package.json | 2 +- 11 files changed, 56 insertions(+), 45 deletions(-) delete mode 100644 change/react-native-windows-2020-04-30-18-28-03-abi-safety.json delete mode 100644 change/react-native-windows-2020-05-09-17-42-52-abi-safety.json delete mode 100644 change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json delete mode 100644 change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json delete mode 100644 change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json diff --git a/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json b/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json deleted file mode 100644 index 7cf31717cd8..00000000000 --- a/change/react-native-windows-2020-04-30-18-28-03-abi-safety.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "none", - "comment": "test bundle build logic, JS function call test", - "packageName": "react-native-windows", - "email": "aeulitz@microsoft.com", - "dependentChangeType": "none", - "date": "2020-05-01T01:28:03.315Z" -} diff --git a/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json b/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json deleted file mode 100644 index ef25becd822..00000000000 --- a/change/react-native-windows-2020-05-09-17-42-52-abi-safety.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "add ReactNativeHost to Win32 C++/WinRT ABI", - "packageName": "react-native-windows", - "email": "aeulitz@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-05-10T00:42:52.866Z" -} diff --git a/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json b/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json deleted file mode 100644 index d3bc77290fd..00000000000 --- a/change/react-native-windows-2020-05-11-11-06-42-FixReactContext.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Fixed ReactContext copy/move semantic", - "packageName": "react-native-windows", - "email": "vmorozov@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-05-11T18:06:42.425Z" -} diff --git a/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json b/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json deleted file mode 100644 index bf2f07e8b92..00000000000 --- a/change/react-native-windows-2020-05-11-13-26-08-devsettingsspec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Use spec file for DevSettings NativeModule", - "packageName": "react-native-windows", - "email": "acoates@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-05-11T20:26:08.523Z" -} diff --git a/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json b/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json deleted file mode 100644 index 6d5da5b4ecf..00000000000 --- a/change/react-native-windows-2020-05-12-14-18-36-OC-4094136-connectxcpt.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "none", - "comment": "Handle HTTP connect exceptions in DevSupportManager", - "packageName": "react-native-windows", - "email": "julio.rocha@microsoft.com", - "dependentChangeType": "none", - "date": "2020-05-12T21:18:36.538Z" -} diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json index a2448e2e4ba..c25b4a7209c 100644 --- a/packages/E2ETest/package.json +++ b/packages/E2ETest/package.json @@ -25,7 +25,7 @@ "prompt-sync": "^4.2.0", "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.64" + "react-native-windows": "0.0.0-master.65" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/microsoft-reactnative-sampleapps/package.json b/packages/microsoft-reactnative-sampleapps/package.json index a994357bb72..9192adc47a2 100644 --- a/packages/microsoft-reactnative-sampleapps/package.json +++ b/packages/microsoft-reactnative-sampleapps/package.json @@ -16,7 +16,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.64" + "react-native-windows": "0.0.0-master.65" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/playground/package.json b/packages/playground/package.json index 55d1d381182..64b1cc263d6 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,7 +11,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.64" + "react-native-windows": "0.0.0-master.65" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json index a53ac0d9280..f5bd3760b42 100644 --- a/vnext/CHANGELOG.json +++ b/vnext/CHANGELOG.json @@ -1,6 +1,47 @@ { "name": "react-native-windows", "entries": [ + { + "date": "Wed, 13 May 2020 00:04:21 GMT", + "tag": "react-native-windows_v0.0.0-master.65", + "version": "0.0.0-master.65", + "comments": { + "none": [ + { + "comment": "test bundle build logic, JS function call test", + "author": "aeulitz@microsoft.com", + "commit": "56e08530db3e751a8813785bb51aeb728aad98b0", + "package": "react-native-windows" + }, + { + "comment": "Handle HTTP connect exceptions in DevSupportManager", + "author": "julio.rocha@microsoft.com", + "commit": "dbe875f5f1445d4a3967b466ad83d0c33d76a53c", + "package": "react-native-windows" + } + ], + "prerelease": [ + { + "comment": "add ReactNativeHost to Win32 C++/WinRT ABI", + "author": "aeulitz@microsoft.com", + "commit": "49e65479d70ab1df738cb7bf21e915e9453eaf13", + "package": "react-native-windows" + }, + { + "comment": "Fixed ReactContext copy/move semantic", + "author": "vmorozov@microsoft.com", + "commit": "d5e8bdcbf63a8ee2e9221bfa344faa227ef892e3", + "package": "react-native-windows" + }, + { + "comment": "Use spec file for DevSettings NativeModule", + "author": "acoates@microsoft.com", + "commit": "8033b548f81e48d904b4dd1b1f81df33dbb232c4", + "package": "react-native-windows" + } + ] + } + }, { "date": "Tue, 12 May 2020 00:04:39 GMT", "tag": "react-native-windows_v0.0.0-master.64", diff --git a/vnext/CHANGELOG.md b/vnext/CHANGELOG.md index b680713a308..2ebe842eed9 100644 --- a/vnext/CHANGELOG.md +++ b/vnext/CHANGELOG.md @@ -1,9 +1,19 @@ # Change Log - react-native-windows -This log was last generated on Tue, 12 May 2020 00:04:39 GMT and should not be manually modified. +This log was last generated on Wed, 13 May 2020 00:04:21 GMT and should not be manually modified. +## 0.0.0-master.65 + +Wed, 13 May 2020 00:04:21 GMT + +### Changes + +- add ReactNativeHost to Win32 C++/WinRT ABI (aeulitz@microsoft.com) +- Fixed ReactContext copy/move semantic (vmorozov@microsoft.com) +- Use spec file for DevSettings NativeModule (acoates@microsoft.com) + ## 0.0.0-master.64 Tue, 12 May 2020 00:04:39 GMT diff --git a/vnext/package.json b/vnext/package.json index 228a39cb384..e8d93f226d0 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.0.0-master.64", + "version": "0.0.0-master.65", "license": "MIT", "repository": { "type": "git", From d1abb363bfcd8dc7f84fec768f32525002109919 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Tue, 12 May 2020 21:44:50 -0700 Subject: [PATCH 15/33] Allow storing non-WinRT types in ReactPropertyBag (#4884) * Allow storing non-WinRT types in ReactPropertyBag * Change files * Addressed PR feedback --- ...-2020-05-12-18-57-59-UnsafePropertyId.json | 8 +++++ vnext/Microsoft.ReactNative.Cxx/BoxedValue.h | 31 +++++++++++++++++++ .../Microsoft.ReactNative.Cxx.vcxitems | 1 + .../Microsoft.ReactNative.Cxx/NativeModules.h | 18 +---------- .../ReactPropertyBag.h | 24 +++++++++++--- .../ReactPropertyBagTests.cpp | 22 +++++++++++++ 6 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 change/react-native-windows-2020-05-12-18-57-59-UnsafePropertyId.json create mode 100644 vnext/Microsoft.ReactNative.Cxx/BoxedValue.h diff --git a/change/react-native-windows-2020-05-12-18-57-59-UnsafePropertyId.json b/change/react-native-windows-2020-05-12-18-57-59-UnsafePropertyId.json new file mode 100644 index 00000000000..2841e2d184d --- /dev/null +++ b/change/react-native-windows-2020-05-12-18-57-59-UnsafePropertyId.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Allow storing non-WinRT types in ReactPropertyBag", + "packageName": "react-native-windows", + "email": "vmorozov@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-13T01:57:59.370Z" +} diff --git a/vnext/Microsoft.ReactNative.Cxx/BoxedValue.h b/vnext/Microsoft.ReactNative.Cxx/BoxedValue.h new file mode 100644 index 00000000000..841391a718b --- /dev/null +++ b/vnext/Microsoft.ReactNative.Cxx/BoxedValue.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#ifndef MICROSOFT_REACTNATIVE_BOXEDVALUE +#define MICROSOFT_REACTNATIVE_BOXEDVALUE + +#include + +namespace winrt::Microsoft::ReactNative { + +template +struct BoxedValue : implements, IBoxedValue> { + template + BoxedValue(TArgs &&... args) noexcept : m_value(std::forward(args)...) {} + + int64_t GetPtr() const noexcept { + return reinterpret_cast(&m_value); + } + + static T &GetValueUnsafe(IBoxedValue const &boxedValue) noexcept { + return *reinterpret_cast(boxedValue.GetPtr()); + } + + private: + T m_value{}; +}; + +} // namespace winrt::Microsoft::ReactNative + +#endif // MICROSOFT_REACTNATIVE_BOXEDVALUE diff --git a/vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems b/vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems index 9a476a959fb..38328ca6aa6 100644 --- a/vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +++ b/vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems @@ -17,6 +17,7 @@ + diff --git a/vnext/Microsoft.ReactNative.Cxx/NativeModules.h b/vnext/Microsoft.ReactNative.Cxx/NativeModules.h index 19ab45c0080..23532730abc 100644 --- a/vnext/Microsoft.ReactNative.Cxx/NativeModules.h +++ b/vnext/Microsoft.ReactNative.Cxx/NativeModules.h @@ -4,6 +4,7 @@ #pragma once #include "winrt/Microsoft.ReactNative.h" +#include "BoxedValue.h" #include "JSValueReader.h" #include "JSValueWriter.h" #include "ModuleRegistration.h" @@ -1105,23 +1106,6 @@ struct TurboModuleSpec { } }; -template -struct BoxedValue : implements, IBoxedValue> { - template - BoxedValue(TArgs &&... args) noexcept : m_value(std::forward(args)...) {} - - int64_t GetPtr() noexcept { - return reinterpret_cast(&m_value); - } - - static T &GetValueUnsafe(IBoxedValue const &boxedValue) noexcept { - return *reinterpret_cast(boxedValue.GetPtr()); - } - - private: - T m_value{}; -}; - template inline ReactModuleProvider MakeModuleProvider() noexcept { return [](IReactModuleBuilder const &moduleBuilder) noexcept { diff --git a/vnext/Microsoft.ReactNative.Cxx/ReactPropertyBag.h b/vnext/Microsoft.ReactNative.Cxx/ReactPropertyBag.h index 1dc6d09bcdf..fcf75ff7a22 100644 --- a/vnext/Microsoft.ReactNative.Cxx/ReactPropertyBag.h +++ b/vnext/Microsoft.ReactNative.Cxx/ReactPropertyBag.h @@ -37,12 +37,14 @@ // directly because their null value may indicated absent property value. // For other types we return std::optional. It has std::nullopt value in case if // no property value is found or if it has a wrong type. -// To avoid compilation errors the non-IInspectable types must be WinRT types which are described here: +// To pass values through the ABI boundary the non-IInspectable types must be WinRT types +// which are described here: // https://docs.microsoft.com/en-us/uwp/api/windows.foundation.propertytype?view=winrt-18362 // #include #include +#include "BoxedValue.h" namespace winrt::Microsoft::ReactNative { @@ -113,10 +115,10 @@ struct ReactPropertyId { IReactPropertyName m_handle; }; -// ReactPropertyBag is a wrapper for IReactPropertyBag to stores strongly-typed properties in a thread-safe way. +// ReactPropertyBag is a wrapper for IReactPropertyBag to store strongly-typed properties in a thread-safe way. // Types inherited from IInspectable are stored directly. // Values of other types are boxed with help of winrt::box_value. -// Only WinRT types can be stored. +// Non-WinRT types are wrapped with the help of BoxedValue template. struct ReactPropertyBag { // Property result type is either T or std::optional. // T is returned for types inherited from IInspectable. @@ -235,7 +237,11 @@ struct ReactPropertyBag { private: template static Windows::Foundation::IInspectable ToObject(T const &value) noexcept { - return winrt::box_value(value); + if constexpr (impl::has_category_v) { + return box_value(value); + } else { + return make>(value); + } } template @@ -247,7 +253,7 @@ struct ReactPropertyBag { static auto FromObject(Windows::Foundation::IInspectable const &obj) noexcept { if constexpr (std::is_base_of_v) { return obj.try_as(); - } else { + } else if constexpr (impl::has_category_v) { if (obj) { #ifdef WINRT_IMPL_IUNKNOWN_DEFINED if constexpr (std::is_same_v) { @@ -267,6 +273,14 @@ struct ReactPropertyBag { } } + return std::optional{}; + } else { + if (obj) { + if (auto temp = obj.try_as()) { + return std::optional{BoxedValue::GetValueUnsafe(temp)}; + } + } + return std::optional{}; } } diff --git a/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp b/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp index 27168257d81..f96cee63e26 100644 --- a/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp +++ b/vnext/Microsoft.ReactNative.IntegrationTests/ReactPropertyBagTests.cpp @@ -6,6 +6,7 @@ using namespace winrt; using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; namespace ReactNativeIntegrationTests { @@ -522,6 +523,27 @@ TEST_CLASS (ReactPropertyBagTests) { pb.Remove(fooName); TestCheck(!pb.Get(fooName)); } + + TEST_METHOD(PropertyBag_Property_Functor) { + ReactPropertyId> fooName{L"Foo"}; + ReactPropertyBag pb{ReactPropertyBagHelper::CreatePropertyBag()}; + + TestCheck(!pb.Get(fooName)); + Mso::Functor createValue1 = []() noexcept { + return winrt::box_value(5); + }; + TestCheckEqual(createValue1, *pb.GetOrCreate(fooName, [&createValue1]() { return createValue1; })); + TestCheckEqual(createValue1, *pb.Get(fooName)); + TestCheckEqual(5, winrt::unbox_value((*pb.Get(fooName))())); + + Mso::Functor createValue2 = []() { return winrt::box_value(10); }; + pb.Set(fooName, createValue2); + TestCheckEqual(createValue2, *pb.Get(fooName)); + TestCheckEqual(10, winrt::unbox_value((*pb.Get(fooName))())); + TestCheck(createValue1 != *pb.Get(fooName)); + pb.Remove(fooName); + TestCheck(!pb.Get(fooName)); + } }; } // namespace ReactNativeIntegrationTests From e6337047f6085b32951eeff4f5063d21e5c7da2f Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Wed, 13 May 2020 11:14:26 -0700 Subject: [PATCH 16/33] Use DispatcherQueue instead of CoreDispatcher for Mso::DispatchQueue (#4877) * Use DispatcherQueue instead of CoreDispatcher for Mso::DispatchQueue * Change files * Removed 'Thread' from some new API names. * Removed extra 'private' section in AppearanceModule * Temporary: use CoreDispatcher to check the E2E test * Avoid using DispatcherQueue::HasThreadAccess in earlier Windows versions. --- ...indows-2020-05-12-11-18-16-MS_UIQueue.json | 8 ++ .../SampleLibraryCPP/SampleModuleCPP.h | 4 +- .../windows/SampleLibraryCS/SampleModuleCS.cs | 4 +- .../playground/windows/playground-win32.sln | 3 + .../IReactDispatcher.cpp | 44 +++++++ .../Microsoft.ReactNative/IReactDispatcher.h | 52 ++++++++ .../IReactDispatcher.idl | 32 +++++ .../Microsoft.ReactNative.vcxproj | 9 +- .../Microsoft.ReactNative.vcxproj.filters | 5 +- .../Modules/AppStateData.cpp | 8 +- .../Modules/AppStateData.h | 4 +- .../ReactApplication.cpp | 2 + .../ReactHost/ReactInstanceWin.cpp | 15 ++- .../ReactHost/ReactInstanceWin.h | 1 + .../ReactInstanceSettings.idl | 2 +- vnext/Microsoft.ReactNative/RedBox.cpp | 54 +++++---- vnext/Microsoft.ReactNative/RedBox.h | 4 +- vnext/Microsoft.ReactNative/RedBoxHandler.cpp | 4 +- .../Threading/MessageQueueThreadFactory.cpp | 3 +- vnext/Mso/dispatchQueue/dispatchQueue.h | 13 +- vnext/Mso/src/dispatchQueue/queueService.cpp | 5 - vnext/Mso/src/dispatchQueue/queueService.h | 2 - .../src/dispatchQueue/uiScheduler_winrt.cpp | 114 +++++++++--------- vnext/ReactUWP/Base/UwpReactInstance.cpp | 2 +- vnext/ReactUWP/Modules/AppearanceModule.cpp | 8 +- vnext/ReactUWP/Modules/AppearanceModule.h | 2 +- vnext/ReactUWP/ReactUWP.vcxproj.filters | 10 +- 27 files changed, 280 insertions(+), 134 deletions(-) create mode 100644 change/react-native-windows-2020-05-12-11-18-16-MS_UIQueue.json create mode 100644 vnext/Microsoft.ReactNative/IReactDispatcher.cpp create mode 100644 vnext/Microsoft.ReactNative/IReactDispatcher.h create mode 100644 vnext/Microsoft.ReactNative/IReactDispatcher.idl diff --git a/change/react-native-windows-2020-05-12-11-18-16-MS_UIQueue.json b/change/react-native-windows-2020-05-12-11-18-16-MS_UIQueue.json new file mode 100644 index 00000000000..aeec541b06c --- /dev/null +++ b/change/react-native-windows-2020-05-12-11-18-16-MS_UIQueue.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Use DispatcherQueue instead of CoreDispatcher for Mso::DispatchQueue", + "packageName": "react-native-windows", + "email": "vmorozov@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-12T18:18:15.956Z" +} diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleModuleCPP.h b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleModuleCPP.h index 87f071637f2..161adc8f9c8 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleModuleCPP.h +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleModuleCPP.h @@ -36,8 +36,8 @@ struct SampleModuleCppImpl { void Initialize(ReactContext const &reactContext) noexcept { const ReactPropertyId myProp1{L"Prop1"}; const ReactPropertyId myProp2{L"Prop2"}; - DEBUG_OUTPUT("globalProps.Prop1:", *reactContext.Properties().Get(myProp1)); - DEBUG_OUTPUT("instanceProps.Prop2:", winrt::to_string(*reactContext.Properties().Get(myProp2))); + DEBUG_OUTPUT("C++ Properties.Prop1:", *reactContext.Properties().Get(myProp1)); + DEBUG_OUTPUT("C++ Properties.Prop2:", winrt::to_string(*reactContext.Properties().Get(myProp2))); m_timer = winrt::Windows::System::Threading::ThreadPoolTimer::CreatePeriodicTimer( [this](const winrt::Windows::System::Threading::ThreadPoolTimer) noexcept { diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCS/SampleModuleCS.cs b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCS/SampleModuleCS.cs index 655e8391d7b..732219ba1e4 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCS/SampleModuleCS.cs +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCS/SampleModuleCS.cs @@ -26,8 +26,8 @@ internal sealed class SampleModuleCS [ReactInitializer] public void Initialize(ReactContext reactContext) { - Debug.WriteLine($"C# globalProps.Prop1: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop1"))}"); - Debug.WriteLine($"C# instanceProps.Prop2: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop2"))}"); + Debug.WriteLine($"C# Properties.Prop1: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop1"))}"); + Debug.WriteLine($"C# Properties.Prop2: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop2"))}"); _timer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler((timer) => { diff --git a/packages/playground/windows/playground-win32.sln b/packages/playground/windows/playground-win32.sln index 3339e428ab1..705febd73f7 100644 --- a/packages/playground/windows/playground-win32.sln +++ b/packages/playground/windows/playground-win32.sln @@ -40,6 +40,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\..\..\vnext\Co EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\..\..\vnext\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\..\..\vnext\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4 @@ -47,6 +49,7 @@ Global ..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4 ..\..\..\vnext\Mso\Mso.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4 ..\..\..\vnext\Shared\Shared.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4 + ..\..\..\vnext\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9 ..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{8b88ffae-4dbc-49a2-afa5-d2477d4ad189}*SharedItemsImports = 4 ..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4 ..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9 diff --git a/vnext/Microsoft.ReactNative/IReactDispatcher.cpp b/vnext/Microsoft.ReactNative/IReactDispatcher.cpp new file mode 100644 index 00000000000..4c394e94825 --- /dev/null +++ b/vnext/Microsoft.ReactNative/IReactDispatcher.cpp @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" +#include "IReactDispatcher.h" +#include "ReactDispatcherHelper.g.cpp" + +using namespace winrt; +using namespace Windows::Foundation; + +namespace winrt::Microsoft::ReactNative { + +ReactDispatcher::ReactDispatcher(Mso::DispatchQueue &&queue) noexcept : m_queue{std::move(queue)} {} + +bool ReactDispatcher::HasThreadAccess() noexcept { + return m_queue.HasThreadAccess(); +} + +void ReactDispatcher::Post(ReactDispatcherCallback const &callback) noexcept { + return m_queue.Post([callback]() noexcept { callback(); }); +} + +/*static*/ Mso::DispatchQueue ReactDispatcher::GetUIDispatchQueue(IReactPropertyBag const &properties) noexcept { + return GetUIDispatcher(properties).as()->m_queue; +} + +/*static*/ IReactDispatcher ReactDispatcher::UIThreadDispatcher() noexcept { + return make(Mso::DispatchQueue::MakeCurrentThreadUIQueue()); +} + +/*static*/ ReactPropertyId ReactDispatcher::UIDispatcherProperty() noexcept { + static ReactPropertyId uiThreadDispatcherProperty{L"ReactNative.Dispatcher", L"UIDispatcher"}; + return uiThreadDispatcherProperty; +} + +/*static*/ IReactDispatcher ReactDispatcher::GetUIDispatcher(IReactPropertyBag const &properties) noexcept { + return ReactPropertyBag{properties}.Get(UIDispatcherProperty()); +} + +/*static*/ void ReactDispatcher::SetUIThreadDispatcher(IReactPropertyBag const &properties) noexcept { + ReactPropertyBag{properties}.Set(UIDispatcherProperty(), UIThreadDispatcher()); +} + +} // namespace winrt::Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/IReactDispatcher.h b/vnext/Microsoft.ReactNative/IReactDispatcher.h new file mode 100644 index 00000000000..e71c0526012 --- /dev/null +++ b/vnext/Microsoft.ReactNative/IReactDispatcher.h @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once +#include "ReactDispatcherHelper.g.h" +#include +#include +#include + +namespace winrt::Microsoft::ReactNative { + +struct ReactDispatcher : implements { + ReactDispatcher() = default; + ReactDispatcher(Mso::DispatchQueue &&queue) noexcept; + + bool HasThreadAccess() noexcept; + void Post(ReactDispatcherCallback const &callback) noexcept; + + static Mso::DispatchQueue GetUIDispatchQueue(IReactPropertyBag const &properties) noexcept; + + static IReactDispatcher UIThreadDispatcher() noexcept; + static ReactPropertyId UIDispatcherProperty() noexcept; + static IReactDispatcher GetUIDispatcher(IReactPropertyBag const &properties) noexcept; + static void SetUIThreadDispatcher(IReactPropertyBag const &properties) noexcept; + + private: + Mso::DispatchQueue m_queue; +}; + +} // namespace winrt::Microsoft::ReactNative + +namespace winrt::Microsoft::ReactNative::implementation { + +struct ReactDispatcherHelper { + ReactDispatcherHelper() = default; + + static IReactDispatcher UIThreadDispatcher() noexcept { + return ReactDispatcher::UIThreadDispatcher(); + } + + static IReactPropertyName UIDispatcherProperty() noexcept { + return ReactDispatcher::UIDispatcherProperty().Handle(); + } +}; + +} // namespace winrt::Microsoft::ReactNative::implementation + +namespace winrt::Microsoft::ReactNative::factory_implementation { + +struct ReactDispatcherHelper : ReactDispatcherHelperT {}; + +} // namespace winrt::Microsoft::ReactNative::factory_implementation diff --git a/vnext/Microsoft.ReactNative/IReactDispatcher.idl b/vnext/Microsoft.ReactNative/IReactDispatcher.idl new file mode 100644 index 00000000000..e5f3d9b6d5f --- /dev/null +++ b/vnext/Microsoft.ReactNative/IReactDispatcher.idl @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import "IReactPropertyBag.idl"; + +namespace Microsoft.ReactNative { + + // The delegate is used to create property value on-demand. + [webhosthidden] + delegate void ReactDispatcherCallback(); + + [webhosthidden] + interface IReactDispatcher + { + // True if dispatcher uses current thread. + Boolean HasThreadAccess { get; }; + + // Post task for the asynchronous execution. + void Post(ReactDispatcherCallback callback); + } + + // Helper methods for the property bag implementation. + [webhosthidden] + static runtimeclass ReactDispatcherHelper + { + // Get or create IReactDispatcher for the current UI thread. + static IReactDispatcher UIThreadDispatcher{ get; }; + + // Get name of the UIDispatcher property for the IReactPropertyBag. + static IReactPropertyName UIDispatcherProperty(); + } +} // namespace ReactNative diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj index 68d21f19ac0..3a981cd2ef6 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj @@ -1,4 +1,4 @@ - + @@ -299,6 +299,9 @@ IJSValueWriter.idl + + IReactDispatcher.idl + IReactModuleBuilder.idl @@ -467,6 +470,9 @@ IJSValueWriter.idl + + IReactDispatcher.idl + IReactModuleBuilder.idl @@ -547,6 +553,7 @@ + diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters index de2019f2870..49caa030be9 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters @@ -265,6 +265,7 @@ + Modules @@ -298,7 +299,6 @@ ReactHost - @@ -599,6 +599,7 @@ Base + Modules @@ -648,7 +649,6 @@ ReactHost - @@ -685,6 +685,7 @@ + diff --git a/vnext/Microsoft.ReactNative/Modules/AppStateData.cpp b/vnext/Microsoft.ReactNative/Modules/AppStateData.cpp index 3f980dcbd45..b3e32f5ca5b 100644 --- a/vnext/Microsoft.ReactNative/Modules/AppStateData.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AppStateData.cpp @@ -11,8 +11,8 @@ using namespace xaml; namespace react::uwp { -AppStateData::AppStateData(Mso::React::IReactContext &reactContext) noexcept - : Super(Mso::DispatchQueue::MainUIQueue()), m_lastState{"active"}, m_reactContext{&reactContext} {} +AppStateData::AppStateData(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept + : Super(uiQueue), m_lastState{"active"}, m_reactContext{&reactContext} {} AppStateData::~AppStateData() = default; @@ -59,8 +59,8 @@ void AppStateData::RaiseEvent(char const *newState) noexcept { "RCTDeviceEventEmitter", "emit", folly::dynamic::array("appStateDidChange", std::move(parameters))); } -AppState2::AppState2(Mso::React::IReactContext &reactContext) noexcept - : m_data{Mso::Make(reactContext)} {} +AppState2::AppState2(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept + : m_data{Mso::Make(reactContext, uiQueue)} {} AppState2::~AppState2() = default; diff --git a/vnext/Microsoft.ReactNative/Modules/AppStateData.h b/vnext/Microsoft.ReactNative/Modules/AppStateData.h index ff400f8af81..48bc55672c5 100644 --- a/vnext/Microsoft.ReactNative/Modules/AppStateData.h +++ b/vnext/Microsoft.ReactNative/Modules/AppStateData.h @@ -15,7 +15,7 @@ namespace react::uwp { struct AppStateData : Mso::ActiveObject<> { using Super = ActiveObjectType; - AppStateData(Mso::React::IReactContext &reactContext) noexcept; + AppStateData(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept; ~AppStateData() override; void Initialize() noexcept override; void Finalize() noexcept override; @@ -36,7 +36,7 @@ struct AppStateData : Mso::ActiveObject<> { // It is a temporary class that we need to keep until we remove ReactUWP class AppState2 : public facebook::react::AppState { public: - AppState2(Mso::React::IReactContext &reactContext) noexcept; + AppState2(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept; public: // facebook::react::AppState ~AppState2() override; diff --git a/vnext/Microsoft.ReactNative/ReactApplication.cpp b/vnext/Microsoft.ReactNative/ReactApplication.cpp index a4f2d1d4e93..ee7263ae52f 100644 --- a/vnext/Microsoft.ReactNative/ReactApplication.cpp +++ b/vnext/Microsoft.ReactNative/ReactApplication.cpp @@ -5,6 +5,7 @@ #include "ReactApplication.h" #include "ReactApplication.g.cpp" +#include "IReactDispatcher.h" #include "Modules/LinkingManagerModule.h" #include "ReactNativeHost.h" @@ -48,6 +49,7 @@ ReactApplication::ReactApplication(IInspectable const &outer) noexcept : ReactAp ReactNative::ReactInstanceSettings ReactApplication::InstanceSettings() noexcept { if (!m_instanceSettings) { m_instanceSettings = make(); + ReactDispatcher::SetUIThreadDispatcher(m_instanceSettings.Properties()); } return m_instanceSettings; diff --git a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp index d5e8e48bba8..6676d038690 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +++ b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp @@ -21,6 +21,7 @@ #include #include +#include "IReactDispatcher.h" #include "Modules/AppStateData.h" #include "Modules/ClipboardModule.h" #include "Modules/DevSettingsModule.h" @@ -154,7 +155,7 @@ void ReactInstanceWin::Initialize() noexcept { InitUIManager(); Mso::PostFuture( - Mso::DispatchQueue::MainUIQueue(), + m_uiQueue, [weakThis = Mso::WeakPtr{this}]() noexcept { // Objects that must be created on the UI thread if (auto strongThis = weakThis.GetStrongPtr()) { @@ -163,7 +164,8 @@ void ReactInstanceWin::Initialize() noexcept { strongThis->m_appTheme = std::make_shared(legacyInstance, strongThis->m_uiMessageThread.LoadWithLock()); react::uwp::I18nHelper().Instance().setInfo(react::uwp::I18nModule::GetI18nInfo()); - strongThis->m_appearanceListener = Mso::Make(legacyInstance); + strongThis->m_appearanceListener = + Mso::Make(legacyInstance, strongThis->m_uiQueue); } }) .Then(Queue(), [ this, weakThis = Mso::WeakPtr{this} ]() noexcept { @@ -199,7 +201,7 @@ void ReactInstanceWin::Initialize() noexcept { devSettings->debuggerConsoleRedirection = false; // JSHost::ChangeGate::ChakraCoreDebuggerConsoleRedirection(); - m_appState = std::make_shared(*m_reactContext); + m_appState = std::make_shared(*m_reactContext, m_uiQueue); // Acquire default modules and then populate with custom modules std::vector cxxModules = react::uwp::GetCoreModules( @@ -457,8 +459,9 @@ void ReactInstanceWin::InitNativeMessageThread() noexcept { void ReactInstanceWin::InitUIMessageThread() noexcept { // Native queue was already given us in constructor. - m_uiMessageThread.Exchange(std::make_shared( - Mso::DispatchQueue::MainUIQueue(), Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError))); + m_uiQueue = winrt::Microsoft::ReactNative::ReactDispatcher::GetUIDispatchQueue(m_options.Properties); + m_uiMessageThread.Exchange( + std::make_shared(m_uiQueue, Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError))); m_batchingUIThread = react::uwp::MakeBatchingQueueThread(m_uiMessageThread.Load()); } @@ -520,7 +523,7 @@ std::shared_ptr ReactInstanceWin::GetRedBoxHandler() noexcept { return m_options.RedBoxHandler; } else if (m_options.DeveloperSettings.IsDevModeEnabled) { auto localWkReactHost = m_weakReactHost; - return CreateDefaultRedBoxHandler(std::move(localWkReactHost)); + return CreateDefaultRedBoxHandler(std::move(localWkReactHost), Mso::Copy(m_uiQueue)); } else { return {}; } diff --git a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h index 7a90f7da41b..5f2957f8389 100644 --- a/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +++ b/vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h @@ -161,6 +161,7 @@ class ReactInstanceWin final : public Mso::ActiveObject m_appTheme; Mso::CntPtr m_appearanceListener; std::string m_bundleRootPath; + Mso::DispatchQueue m_uiQueue; }; } // namespace Mso::React diff --git a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl index f388e735f29..fff4532c2d4 100644 --- a/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl +++ b/vnext/Microsoft.ReactNative/ReactInstanceSettings.idl @@ -30,6 +30,6 @@ namespace Microsoft.ReactNative { String DebugBundlePath { get; set; }; String BundleRootPath { get; set; }; UInt16 DebuggerPort { get; set; }; - Microsoft.ReactNative.IRedBoxHandler RedBoxHandler { get; set; }; + IRedBoxHandler RedBoxHandler { get; set; }; } } diff --git a/vnext/Microsoft.ReactNative/RedBox.cpp b/vnext/Microsoft.ReactNative/RedBox.cpp index 699454c743e..0491a64fc9a 100644 --- a/vnext/Microsoft.ReactNative/RedBox.cpp +++ b/vnext/Microsoft.ReactNative/RedBox.cpp @@ -358,19 +358,19 @@ struct RedBox : public std::enable_shared_from_this { * This class is implemented such that the methods on IRedBoxHandler are thread safe. */ struct DefaultRedBoxHandler : public std::enable_shared_from_this, IRedBoxHandler { - DefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept - : m_weakReactHost(std::move(weakReactHost)) {} + DefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost, Mso::DispatchQueue &&uiQueue) noexcept + : m_weakReactHost{std::move(weakReactHost)}, m_uiQueue{std::move(uiQueue)} {} ~DefaultRedBoxHandler() { - // Hide any currently showing redboxes - std::vector> redboxes; + // Hide any currently showing redBoxes + std::vector> redBoxes; { std::scoped_lock lock{m_lockRedBox}; - std::swap(m_redboxes, redboxes); + std::swap(m_redBoxes, redBoxes); } - Mso::DispatchQueue::MainUIQueue().Post([redboxes = std::move(redboxes)]() { - for (const auto redbox : redboxes) { - redbox->Dismiss(); + m_uiQueue.Post([redBoxes = std::move(redBoxes)]() { + for (const auto redBox : redBoxes) { + redBox->Dismiss(); } }); } @@ -386,7 +386,7 @@ struct DefaultRedBoxHandler : public std::enable_shared_from_this redbox; { std::scoped_lock lock{m_lockRedBox}; - for (auto it = m_redboxes.begin(); it != m_redboxes.end(); ++it) { + for (auto it = m_redBoxes.begin(); it != m_redBoxes.end(); ++it) { if ((*it)->GetId() == info.Id) { redbox = *it; break; } } } + if (redbox) { - Mso::DispatchQueue::MainUIQueue().Post([redboxCaptured = std::move(redbox), errorInfo = std::move(info)]() { + m_uiQueue.Post([redboxCaptured = std::move(redbox), errorInfo = std::move(info)]() { redboxCaptured->UpdateError(std::move(errorInfo)); }); } } virtual void dismissRedbox() override { - Mso::DispatchQueue::MainUIQueue().Post([wkthis = std::weak_ptr(shared_from_this())]() { + m_uiQueue.Post([wkthis = std::weak_ptr(shared_from_this())]() { if (auto pthis = wkthis.lock()) { std::scoped_lock lock{pthis->m_lockRedBox}; - if (!pthis->m_redboxes.empty()) - pthis->m_redboxes[0]->Dismiss(); + if (!pthis->m_redBoxes.empty()) + pthis->m_redBoxes[0]->Dismiss(); } }); } private: - // When notified by a redbox that its been dismisssed + // When notified by a redbox that its been dismissed void onDismissedCallback(uint32_t id) noexcept { // Save a local ref, so if we are removing the last redbox which could hold the last ref to the DefaultRedBoxHandler // We ensure that we exit the mutex before the handler is destroyed. @@ -436,10 +437,10 @@ struct DefaultRedBoxHandler : public std::enable_shared_from_thisGetId() == id) { redbox = *it; - it = m_redboxes.erase(it); + it = m_redBoxes.erase(it); break; } } @@ -453,8 +454,8 @@ struct DefaultRedBoxHandler : public std::enable_shared_from_this redbox; { std::scoped_lock lock{m_lockRedBox}; - if (!m_redboxes.empty()) { - redbox = m_redboxes[0]; + if (!m_redBoxes.empty()) { + redbox = m_redBoxes[0]; } } @@ -462,13 +463,14 @@ struct DefaultRedBoxHandler : public std::enable_shared_from_thisShowNewJSError(); }); + m_uiQueue.Post([redboxCaptured = std::move(redbox)]() { redboxCaptured->ShowNewJSError(); }); } - bool m_showingRedBox = false; // Access from UI Thread only + private: + const Mso::DispatchQueue m_uiQueue; + bool m_showingRedBox{false}; // Access from UI Thread only std::mutex m_lockRedBox; - std::vector> m_redboxes; // Protected by m_lockRedBox + std::vector> m_redBoxes; // Protected by m_lockRedBox const Mso::WeakPtr m_weakReactHost; }; @@ -564,8 +566,10 @@ std::shared_ptr CreateRedBoxHandler( return std::make_shared(redBoxHandler); } -std::shared_ptr CreateDefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept { - return std::make_shared(std::move(weakReactHost)); +std::shared_ptr CreateDefaultRedBoxHandler( + Mso::WeakPtr &&weakReactHost, + Mso::DispatchQueue &&uiQueue) noexcept { + return std::make_shared(std::move(weakReactHost), std::move(uiQueue)); } } // namespace Mso::React diff --git a/vnext/Microsoft.ReactNative/RedBox.h b/vnext/Microsoft.ReactNative/RedBox.h index 0a14590aaea..8d0672a2a54 100644 --- a/vnext/Microsoft.ReactNative/RedBox.h +++ b/vnext/Microsoft.ReactNative/RedBox.h @@ -10,6 +10,8 @@ namespace Mso::React { std::shared_ptr CreateRedBoxHandler( winrt::Microsoft::ReactNative::IRedBoxHandler const &redBoxHandler) noexcept; -std::shared_ptr CreateDefaultRedBoxHandler(Mso::WeakPtr &&weakReactHost) noexcept; +std::shared_ptr CreateDefaultRedBoxHandler( + Mso::WeakPtr &&weakReactHost, + Mso::DispatchQueue &&uiQueue) noexcept; } // namespace Mso::React diff --git a/vnext/Microsoft.ReactNative/RedBoxHandler.cpp b/vnext/Microsoft.ReactNative/RedBoxHandler.cpp index 945bece5241..a368c5bb21f 100644 --- a/vnext/Microsoft.ReactNative/RedBoxHandler.cpp +++ b/vnext/Microsoft.ReactNative/RedBoxHandler.cpp @@ -7,6 +7,7 @@ #include "RedBoxHelper.g.cpp" #endif +#include #include #include #include @@ -32,7 +33,8 @@ struct DefaultRedBoxHandler : winrt::implements(host); Mso::WeakPtr wkHost(hostImpl->ReactHost()); - m_redBoxHandler = Mso::React::CreateDefaultRedBoxHandler(std::move(wkHost)); + m_redBoxHandler = Mso::React::CreateDefaultRedBoxHandler( + std::move(wkHost), ReactDispatcher::GetUIDispatchQueue(host.InstanceSettings().Properties())); } void ShowNewError(IRedBoxErrorInfo const &info, RedBoxErrorType type) noexcept { diff --git a/vnext/Microsoft.ReactNative/Threading/MessageQueueThreadFactory.cpp b/vnext/Microsoft.ReactNative/Threading/MessageQueueThreadFactory.cpp index cae018a7568..1dfd9e4f3c5 100644 --- a/vnext/Microsoft.ReactNative/Threading/MessageQueueThreadFactory.cpp +++ b/vnext/Microsoft.ReactNative/Threading/MessageQueueThreadFactory.cpp @@ -12,7 +12,8 @@ std::shared_ptr MakeJSQueueThread() noexcep } std::shared_ptr MakeUIQueueThread() noexcept { - return std::make_shared(Mso::DispatchQueue::MainUIQueue(), nullptr, nullptr); + return std::make_shared( + Mso::DispatchQueue::MakeCurrentThreadUIQueue(), nullptr, nullptr); } std::shared_ptr MakeSerialQueueThread() noexcept { diff --git a/vnext/Mso/dispatchQueue/dispatchQueue.h b/vnext/Mso/dispatchQueue/dispatchQueue.h index a7c1c0a4a20..50e2ecbe1e0 100644 --- a/vnext/Mso/dispatchQueue/dispatchQueue.h +++ b/vnext/Mso/dispatchQueue/dispatchQueue.h @@ -113,9 +113,6 @@ struct DispatchQueue { //! demand. static DispatchQueue const &ConcurrentQueue() noexcept; - //! Get DispatchQueue associated with the main UI thread. It is created on demand. - static DispatchQueue const &MainUIQueue() noexcept; - //! Create new serial DispatchQueue on top of platform specific thread pool. static DispatchQueue MakeSerialQueue() noexcept; @@ -158,8 +155,7 @@ struct DispatchQueue { //! True if tasks are invoked in a serial order by the queue. bool IsSerial() const noexcept; - //! True if queue is running on current thread or associated with it. E.g. MainUIQueue always returns true for the - //! main UI thread. + //! True if queue is running on current thread or associated with it. bool HasThreadAccess() const noexcept; //! Check if a long running task should yield. @@ -416,9 +412,6 @@ struct IDispatchQueueStatic : IUnknown { //! demand. virtual DispatchQueue const &ConcurrentQueue() noexcept = 0; - //! Get DispatchQueue associated with the main UI thread. It is created on demand. - virtual DispatchQueue const &MainUIQueue() noexcept = 0; - //! Create new serial DispatchQueue on top of platform specific thread pool. virtual DispatchQueue MakeSerialQueue() noexcept = 0; @@ -545,10 +538,6 @@ inline /*static*/ DispatchQueue const &DispatchQueue::ConcurrentQueue() noexcept return IDispatchQueueStatic::Instance()->ConcurrentQueue(); } -inline /*static*/ DispatchQueue const &DispatchQueue::MainUIQueue() noexcept { - return IDispatchQueueStatic::Instance()->MainUIQueue(); -} - inline /*static*/ DispatchQueue DispatchQueue::MakeSerialQueue() noexcept { return IDispatchQueueStatic::Instance()->MakeSerialQueue(); } diff --git a/vnext/Mso/src/dispatchQueue/queueService.cpp b/vnext/Mso/src/dispatchQueue/queueService.cpp index b560a732173..d30f444bdc0 100644 --- a/vnext/Mso/src/dispatchQueue/queueService.cpp +++ b/vnext/Mso/src/dispatchQueue/queueService.cpp @@ -269,11 +269,6 @@ DispatchQueue const &DispatchQueueStatic::ConcurrentQueue() noexcept { return *static_cast(static_cast(&concurrentQueue)); } -DispatchQueue const &DispatchQueueStatic::MainUIQueue() noexcept { - static auto mainUIQueue{Mso::Make(MakeMainUIScheduler())}; - return *static_cast(static_cast(&mainUIQueue)); -} - DispatchQueue DispatchQueueStatic::MakeSerialQueue() noexcept { return Mso::Make(MakeThreadPoolScheduler(/*maxThreads:*/ 1)); } diff --git a/vnext/Mso/src/dispatchQueue/queueService.h b/vnext/Mso/src/dispatchQueue/queueService.h index 0d1b30a9734..a80f72a669b 100644 --- a/vnext/Mso/src/dispatchQueue/queueService.h +++ b/vnext/Mso/src/dispatchQueue/queueService.h @@ -82,14 +82,12 @@ struct QueueLocalValueEntry { struct DispatchQueueStatic : Mso::UnknownObject { static DispatchQueueStatic *Instance() noexcept; static Mso::CntPtr MakeLooperScheduler() noexcept; - static Mso::CntPtr MakeMainUIScheduler() noexcept; static Mso::CntPtr MakeCurrentThreadUIScheduler() noexcept; static Mso::CntPtr MakeThreadPoolScheduler(uint32_t maxThreads) noexcept; public: // IDispatchQueueStatic DispatchQueue CurrentQueue() noexcept override; DispatchQueue const &ConcurrentQueue() noexcept override; - DispatchQueue const &MainUIQueue() noexcept override; DispatchQueue MakeSerialQueue() noexcept override; DispatchQueue MakeLooperQueue() noexcept override; DispatchQueue MakeCurrentThreadUIQueue() noexcept override; diff --git a/vnext/Mso/src/dispatchQueue/uiScheduler_winrt.cpp b/vnext/Mso/src/dispatchQueue/uiScheduler_winrt.cpp index 1753023d3a1..70981a780a1 100644 --- a/vnext/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +++ b/vnext/Mso/src/dispatchQueue/uiScheduler_winrt.cpp @@ -5,38 +5,36 @@ #include "object/refCountedObject.h" #include "queueService.h" #include "taskQueue.h" -#include "winrt/Windows.ApplicationModel.Core.h" -#include "winrt/Windows.UI.Core.h" +#include "winrt/Windows.System.h" using namespace winrt; -using namespace Windows::ApplicationModel::Core; -using namespace Windows::UI::Core; +using namespace Windows::System; namespace Mso { -struct UISchdulerWinRT; +struct UISchedulerWinRT; -//! TaskDispatchedHandler is a DispatchedHandler delegate that we pass to CoreDispatcher. +//! TaskDispatcherHandler is a DispatcherQueueHandler delegate that we pass to DispatcherQueue. //! We use custom ref counting to avoid extra memory allocations and to handle reference to DispatchTask. -struct TaskDispatchedHandler final : impl::abi_t { - TaskDispatchedHandler(UISchdulerWinRT *scheduler) noexcept; +struct TaskDispatcherHandler final : impl::abi_t { + TaskDispatcherHandler(UISchedulerWinRT *scheduler) noexcept; int32_t __stdcall QueryInterface(guid const &id, void **result) noexcept final; uint32_t __stdcall AddRef() noexcept final; uint32_t __stdcall Release() noexcept final; int32_t __stdcall Invoke() noexcept final; private: - UISchdulerWinRT *m_scheduler; + UISchedulerWinRT *m_scheduler; }; -struct UISchdulerWinRT : Mso::UnknownObject { - UISchdulerWinRT(CoreDispatcher &&coreDispatcher) noexcept; - ~UISchdulerWinRT() noexcept override; +struct UISchedulerWinRT : Mso::UnknownObject { + UISchedulerWinRT(DispatcherQueue &&dispatcher) noexcept; + ~UISchedulerWinRT() noexcept override; uint32_t AddHandlerRef() noexcept; uint32_t ReleaseHandlerRef() noexcept; - DispatchedHandler MakeDispatchedHandler() noexcept; + DispatcherQueueHandler MakeDispatcherQueueHandler() noexcept; bool TryTakeTask(Mso::CntPtr &queue, DispatchTask &task) noexcept; public: // IDispatchQueueScheduler @@ -49,39 +47,40 @@ struct UISchdulerWinRT : Mso::UnknownObject m_queue; - Mso::CntPtr m_self; + Mso::CntPtr m_self; uint32_t m_handlerRefCount{0}; uint32_t m_taskCount{0}; bool m_isShutdown{false}; + std::thread::id m_threadId{std::this_thread::get_id()}; }; //============================================================================= -// TaskDispatchedHandler implementation +// TaskDispatcherHandler implementation //============================================================================= -TaskDispatchedHandler::TaskDispatchedHandler(UISchdulerWinRT *scheduler) noexcept : m_scheduler{scheduler} {} +TaskDispatcherHandler::TaskDispatcherHandler(UISchedulerWinRT *scheduler) noexcept : m_scheduler{scheduler} {} -int32_t __stdcall TaskDispatchedHandler::QueryInterface(guid const &id, void **result) noexcept { - if (is_guid_of(id) || is_guid_of(id) || +int32_t __stdcall TaskDispatcherHandler::QueryInterface(guid const &id, void **result) noexcept { + if (is_guid_of(id) || is_guid_of(id) || is_guid_of(id)) { - *result = static_cast *>(this); + *result = static_cast *>(this); AddRef(); return impl::error_ok; } @@ -94,15 +93,15 @@ int32_t __stdcall TaskDispatchedHandler::QueryInterface(guid const &id, void **r return impl::error_no_interface; } -uint32_t __stdcall TaskDispatchedHandler::AddRef() noexcept { +uint32_t __stdcall TaskDispatcherHandler::AddRef() noexcept { return m_scheduler->AddHandlerRef(); } -uint32_t __stdcall TaskDispatchedHandler::Release() noexcept { +uint32_t __stdcall TaskDispatcherHandler::Release() noexcept { return m_scheduler->ReleaseHandlerRef(); } -int32_t __stdcall TaskDispatchedHandler::Invoke() noexcept { +int32_t __stdcall TaskDispatcherHandler::Invoke() noexcept { Mso::CntPtr queue; DispatchTask task; if (m_scheduler->TryTakeTask(queue, task)) { @@ -113,23 +112,22 @@ int32_t __stdcall TaskDispatchedHandler::Invoke() noexcept { } //============================================================================= -// UISchdulerWinRT implementation +// UISchedulerWinRT implementation //============================================================================= -UISchdulerWinRT::UISchdulerWinRT(CoreDispatcher &&coreDispatcher) noexcept - : m_coreDispatcher{std::move(coreDispatcher)} {} +UISchedulerWinRT::UISchedulerWinRT(DispatcherQueue &&dispatcher) noexcept : m_dispatcher{std::move(dispatcher)} {} -UISchdulerWinRT::~UISchdulerWinRT() noexcept { +UISchedulerWinRT::~UISchedulerWinRT() noexcept { AwaitTermination(); } -uint32_t UISchdulerWinRT::AddHandlerRef() noexcept { +uint32_t UISchedulerWinRT::AddHandlerRef() noexcept { std::lock_guard lock{m_mutex}; return ++m_handlerRefCount; } -uint32_t UISchdulerWinRT::ReleaseHandlerRef() noexcept { - Mso::CntPtr self; +uint32_t UISchedulerWinRT::ReleaseHandlerRef() noexcept { + Mso::CntPtr self; CleanupContext context{this}; { @@ -147,7 +145,7 @@ uint32_t UISchdulerWinRT::ReleaseHandlerRef() noexcept { } } -bool UISchdulerWinRT::TryTakeTask(Mso::CntPtr &queue, DispatchTask &task) noexcept { +bool UISchedulerWinRT::TryTakeTask(Mso::CntPtr &queue, DispatchTask &task) noexcept { { std::lock_guard lock{m_mutex}; VerifyElseCrashSz(m_taskCount, "Task count cannot be negative"); @@ -161,45 +159,47 @@ bool UISchdulerWinRT::TryTakeTask(Mso::CntPtr &queue, Dis return false; } -DispatchedHandler UISchdulerWinRT::MakeDispatchedHandler() noexcept { +DispatcherQueueHandler UISchedulerWinRT::MakeDispatcherQueueHandler() noexcept { VerifyElseCrash(m_mutex.IsLockedByMe()); if (m_handlerRefCount == 0) { - m_self = this; // Keep reference to self while CoreDispatcher owns DispatchedHandler. + m_self = this; // Keep reference to self while DispatcherQueue owns DispatcherQueueHandler. } ++m_handlerRefCount; - return {static_cast(&m_dispatchedHandler), take_ownership_from_abi}; + return {static_cast(&m_dispatcherHandler), take_ownership_from_abi}; } -void UISchdulerWinRT::IntializeScheduler(Mso::WeakPtr &&queue) noexcept { +void UISchedulerWinRT::IntializeScheduler(Mso::WeakPtr &&queue) noexcept { m_queue = std::move(queue); } -bool UISchdulerWinRT::HasThreadAccess() noexcept { - return m_coreDispatcher.HasThreadAccess(); +bool UISchedulerWinRT::HasThreadAccess() noexcept { + // m_dispatcher.HasThreadAccess() is implemented only in Windows 19H1. + // We must use an alternative implementation. + return m_threadId == std::this_thread::get_id(); } -bool UISchdulerWinRT::IsSerial() noexcept { +bool UISchedulerWinRT::IsSerial() noexcept { return true; } -void UISchdulerWinRT::Post() noexcept { - DispatchedHandler handler; +void UISchedulerWinRT::Post() noexcept { + DispatcherQueueHandler handler; { std::lock_guard lock{m_mutex}; if (!m_isShutdown) { ++m_taskCount; - handler = MakeDispatchedHandler(); + handler = MakeDispatcherQueueHandler(); } } if (handler) { - m_coreDispatcher.RunAsync(CoreDispatcherPriority::Normal, std::move(handler)); + m_dispatcher.TryEnqueue(handler); } } -void UISchdulerWinRT::Shutdown() noexcept { +void UISchedulerWinRT::Shutdown() noexcept { CleanupContext context{this}; { std::lock_guard lock{m_mutex}; @@ -208,18 +208,18 @@ void UISchdulerWinRT::Shutdown() noexcept { } } -void UISchdulerWinRT::AwaitTermination() noexcept { +void UISchedulerWinRT::AwaitTermination() noexcept { Shutdown(); m_terminationEvent.Wait(); } //============================================================================= -// UISchdulerWinRT::CleanupContext implementation +// UISchedulerWinRT::CleanupContext implementation //============================================================================= -UISchdulerWinRT::CleanupContext::CleanupContext(UISchdulerWinRT *scheduler) noexcept : m_scheduler{scheduler} {} +UISchedulerWinRT::CleanupContext::CleanupContext(UISchedulerWinRT *scheduler) noexcept : m_scheduler{scheduler} {} -UISchdulerWinRT::CleanupContext::~CleanupContext() noexcept { +UISchedulerWinRT::CleanupContext::~CleanupContext() noexcept { if (m_isTerminated) { m_scheduler->m_terminationEvent.Set(); } @@ -231,8 +231,8 @@ UISchdulerWinRT::CleanupContext::~CleanupContext() noexcept { } } -void UISchdulerWinRT::CleanupContext::CheckShutdown() noexcept { - // See if core dispatcher released all handlers without invoking them. +void UISchedulerWinRT::CleanupContext::CheckShutdown() noexcept { + // See if dispatcher queue released all handlers without invoking them. if (m_scheduler->m_taskCount != 0 && m_scheduler->m_handlerRefCount == 0) { m_isShutdown = true; m_scheduler->m_taskCount = 0; @@ -240,20 +240,16 @@ void UISchdulerWinRT::CleanupContext::CheckShutdown() noexcept { } } -void UISchdulerWinRT::CleanupContext::CheckTermination() noexcept { +void UISchedulerWinRT::CleanupContext::CheckTermination() noexcept { m_isTerminated = m_scheduler->m_isShutdown && (m_scheduler->m_handlerRefCount == 0); } //============================================================================= -// DispatchQueueStatic::MakeThreadPoolScheduler implementation +// DispatchQueueStatic::MakeCurrentThreadUIScheduler implementation //============================================================================= -/*static*/ Mso::CntPtr DispatchQueueStatic::MakeMainUIScheduler() noexcept { - return Mso::Make(CoreApplication::MainView().CoreWindow().Dispatcher()); -} - /*static*/ Mso::CntPtr DispatchQueueStatic::MakeCurrentThreadUIScheduler() noexcept { - return Mso::Make(CoreWindow::GetForCurrentThread().Dispatcher()); + return Mso::Make(DispatcherQueue::GetForCurrentThread()); } } // namespace Mso diff --git a/vnext/ReactUWP/Base/UwpReactInstance.cpp b/vnext/ReactUWP/Base/UwpReactInstance.cpp index ce74a02918b..3f447c313b0 100644 --- a/vnext/ReactUWP/Base/UwpReactInstance.cpp +++ b/vnext/ReactUWP/Base/UwpReactInstance.cpp @@ -115,7 +115,7 @@ void UwpReactInstance::Start(const std::shared_ptr &spThis, cons std::shared_ptr appTheme = std::make_shared(spThis, m_defaultNativeThread); I18nHelper::Instance().setInfo(I18nModule::GetI18nInfo()); - auto appearanceListener = Mso::Make(spThis); + auto appearanceListener = Mso::Make(spThis, Mso::DispatchQueue::MakeCurrentThreadUIQueue()); // TODO: Figure out threading. What thread should this really be on? m_initThread = std::make_unique(); diff --git a/vnext/ReactUWP/Modules/AppearanceModule.cpp b/vnext/ReactUWP/Modules/AppearanceModule.cpp index 8f4bba5fa6e..0405de975a2 100644 --- a/vnext/ReactUWP/Modules/AppearanceModule.cpp +++ b/vnext/ReactUWP/Modules/AppearanceModule.cpp @@ -14,10 +14,12 @@ using Method = facebook::xplat::module::CxxModule::Method; namespace react::uwp { -AppearanceChangeListener::AppearanceChangeListener(std::weak_ptr &&reactInstance) noexcept - : Mso::ActiveObject<>(Mso::DispatchQueue::MainUIQueue()), m_weakReactInstance(std::move(reactInstance)) { +AppearanceChangeListener::AppearanceChangeListener( + std::weak_ptr &&reactInstance, + Mso::DispatchQueue const &uiQueue) noexcept + : Mso::ActiveObject<>(uiQueue), m_weakReactInstance(std::move(reactInstance)) { // Ensure we're constructed on the UI thread - VerifyIsInQueueElseCrash(); + VerifyElseCrash(uiQueue.HasThreadAccess()); m_currentTheme = Application::Current().RequestedTheme(); diff --git a/vnext/ReactUWP/Modules/AppearanceModule.h b/vnext/ReactUWP/Modules/AppearanceModule.h index 275c36a3819..1e3b7c6268e 100644 --- a/vnext/ReactUWP/Modules/AppearanceModule.h +++ b/vnext/ReactUWP/Modules/AppearanceModule.h @@ -17,7 +17,7 @@ class AppearanceChangeListener final : public Mso::ActiveObject<> { using UISettings = winrt::Windows::UI::ViewManagement::UISettings; public: - AppearanceChangeListener(std::weak_ptr &&reactInstance) noexcept; + AppearanceChangeListener(std::weak_ptr &&reactInstance, Mso::DispatchQueue const &uiQueue) noexcept; const char *GetColorScheme() const noexcept; private: diff --git a/vnext/ReactUWP/ReactUWP.vcxproj.filters b/vnext/ReactUWP/ReactUWP.vcxproj.filters index 30f2d7c7f54..cc8de5168af 100644 --- a/vnext/ReactUWP/ReactUWP.vcxproj.filters +++ b/vnext/ReactUWP/ReactUWP.vcxproj.filters @@ -106,6 +106,9 @@ Modules\Animated + + Modules + Modules @@ -166,6 +169,7 @@ Polyester + Threading @@ -322,8 +326,6 @@ Views - - @@ -482,6 +484,9 @@ Modules\Animated + + Modules + Modules @@ -657,7 +662,6 @@ Views - From 64aede7aedb329e97df0f6d4f8c946e6454b573c Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 12:24:24 -0700 Subject: [PATCH 17/33] RNW dependencies (#4876) * add rnw-dependencies.ps1 * Change files * --sln * run in CI * print * desktop appium is optional * use agent directory * 15GB is a ballpark estimate * optional space * . --- .ado/windows-vs-pr.yml | 7 + ...-2020-05-11-17-22-16-rnw-dependencies.json | 8 + docs/building-rnw.md | 4 +- vnext/Scripts/rnw-dependencies.ps1 | 147 ++++++++++++++++++ 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 change/react-native-windows-2020-05-11-17-22-16-rnw-dependencies.json create mode 100644 vnext/Scripts/rnw-dependencies.ps1 diff --git a/.ado/windows-vs-pr.yml b/.ado/windows-vs-pr.yml index 3a9f922b1bd..5bdccb68324 100644 --- a/.ado/windows-vs-pr.yml +++ b/.ado/windows-vs-pr.yml @@ -65,6 +65,13 @@ jobs: clean: false submodules: false + - task: PowerShell@2 + displayName: "Check if this environment meets the development dependencies" + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\vnext\Scripts\rnw-dependencies.ps1 + arguments: -NoPrompt + - template: templates/build-rnw.yml parameters: yarnBuildCmd: build diff --git a/change/react-native-windows-2020-05-11-17-22-16-rnw-dependencies.json b/change/react-native-windows-2020-05-11-17-22-16-rnw-dependencies.json new file mode 100644 index 00000000000..c4d7af43b9f --- /dev/null +++ b/change/react-native-windows-2020-05-11-17-22-16-rnw-dependencies.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "add rnw-dependencies.ps1", + "packageName": "react-native-windows", + "email": "asklar@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-12T00:22:16.000Z" +} diff --git a/docs/building-rnw.md b/docs/building-rnw.md index 3dd61b188ae..7b09e5cbbbf 100644 --- a/docs/building-rnw.md +++ b/docs/building-rnw.md @@ -22,7 +22,7 @@ Note that react-native-windows is a monorepo and relies on monorepo tools like y There are two ways to run the app. In a fully managed easy way, or by manually running all the required steps: ## Automatic -The playground app can be run in a completely automatic way by using `react-native run-windows`. +The playground app can be run in a completely automatic way by using `react-native run-windows --sln windows\playground.sln`. If you haven't already, install the react-native-cli (One time only!) ```cmd @@ -33,7 +33,7 @@ Then ```cmd cd packages\playground -react-native run-windows +react-native run-windows --sln windows\playground.sln ``` ## Manual diff --git a/vnext/Scripts/rnw-dependencies.ps1 b/vnext/Scripts/rnw-dependencies.ps1 new file mode 100644 index 00000000000..ab27b0519ff --- /dev/null +++ b/vnext/Scripts/rnw-dependencies.ps1 @@ -0,0 +1,147 @@ +# Troubleshoot RNW dependencies +param([switch]$Install = $false, [switch]$NoPrompt = $false) +$vsWorkloads = @( 'Microsoft.Component.MSBuild', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', 'Microsoft.VisualStudio.ComponentGroup.UWP.Support'); + +$v = [System.Environment]::OSVersion.Version; +if ($env:Agent_BuildDirectory) { + $drive = (Resolve-Path $env:Agent_BuildDirectory).Drive +} else { + $drive = (Resolve-Path $PSCommandPath).Drive +} + +function CheckVS { + $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (!(Test-Path $vsWhere)) { + return $false; + } + $output = & $vsWhere -version 16 -requires $vsWorkloads -property productPath + return Test-Path $output; +} + +function InstallVS { + $installerPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"; + $vsWhere = "$installerPath\vswhere.exe" + if (!(Test-Path $vsWhere)) { + # No VSWhere / VS_Installer + & choco install -y visualstudio2019community + } + $channelId = & $vsWhere -version 16 -property channelId + $productId = & $vsWhere -version 16 -property productId + $vsInstaller = "$installerPath\vs_installer.exe" + $addWorkloads = $vsWorkloads | % { '--add', $_ }; + Start-Process -PassThru -Wait -Path $vsInstaller -ArgumentList ("install --channelId $channelId --productId $productId $addWorkloads --quiet" -split ' ') + +} + +function CheckNode { + try { + $v = (Get-Command node).Version.Major + return $v -eq 12 -or $v -eq 13 + } catch { + return $false; + } +} + +function GetChocoPkgVersion{ + params([string]$packageId) + [version]$version = (& choco list --local-only $packageId -r -e).Substring($packageId.Length + 1); + return $version; +} + +$requiredFreeSpaceGB = 15; + +$requirements = @( + @{ + Name = "Free space on $drive`: > $requiredFreeSpaceGB GB"; + Valid = $drive.Free/1GB -gt $requiredFreeSpaceGB; + Optional = $true # this requirement is fuzzy + }, + @{ + Name = 'Windows version > 10.0.16299.0'; + Valid = ($v.Major -eq 10 -and $v.Minor -eq 0 -and $v.Build -ge 16299) + }, + @{ + Name = 'Developer mode is on'; + Valid = try { (Get-WindowsDeveloperLicense).IsValid } catch { $false } + }, + @{ + Name = 'git'; + Valid = try { (Get-Command git.exe) -ne $null } catch { $false } + } + @{ + Name = 'Choco'; + Valid = try { (Get-Command choco) -ne $null } catch { $false }; + Install = { + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + }; + }, + @{ + Name = 'VS 2019 with UWP and Desktop/C++'; + Valid = CheckVS + }, + @{ + Name = 'NodeJS 12 or 13 installed'; + Valid = CheckNode + Install = { choco install -y nodejs.install --version=12.9.1 } + }, + @{ + Name = 'Chrome'; + Valid = try { ((Get-Item (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe').'(Default)').VersionInfo).ProductMajorPart + } catch { $false } ; + Install = { choco install -y GoogleChrome } + }, + @{ + Name = 'Yarn'; + Valid = try { (Get-Command yarn) -ne $null } catch { $false }; + Install = { choco install -y yarn } + }, + @{ + Name = 'Appium'; + Valid = (Test-Path "${env:ProgramFiles}\Appium\Appium.exe"); + Install = { choco install -y Appium-desktop }; + Optional = $true + }, + @{ + Name = 'WinAppDriver'; + Valid = (Test-Path "${env:ProgramFiles(x86)}\Windows Application Driver\WinAppDriver.exe"); + Install = { choco install -y WinAppDriver }; + } + + ); + +function IsElevated { + return [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544"); +} + +if (!(IsElevated)) { + Write-Output "rnw-dependencies - this script must run elevated. Exiting."; + return; +} + +$NeedsRerun = $false +foreach ($req in $requirements) +{ + Write-Output "Checking $($req.Name)"; + if (!($req.Valid)) { + Write-Output "Requirement failed: $($req.Name)"; + if ($req.Install) { + if ($Install -or (!$NoPrompt -and (Read-Host "Do you want to install? ").ToUpperInvariant() -eq 'Y')) { + Invoke-Command $req.Install -ErrorAction Stop + if ($LASTEXITCODE -ne 0) { throw "Last exit code was non-zero: $LASTEXITCODE"; } + } elseif (!$req.Optional) { + $NeedsRerun = $true; + } + } else { + $NeedsRerun = !($req.Optional); + } + } +} + +if ($NeedsRerun) { + Write-Output "Some dependencies are not met. Re-run with -Install to install them."; + exit 1; +} else { + Write-Output "All mandatory requirements met"; + exit 0; +} From c27b5854a1f0d8e84f31d55284bc3f6b9347cefc Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 13:00:52 -0700 Subject: [PATCH 18/33] support running from web (#4892) --- vnext/Scripts/rnw-dependencies.ps1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vnext/Scripts/rnw-dependencies.ps1 b/vnext/Scripts/rnw-dependencies.ps1 index ab27b0519ff..d91ee41d40d 100644 --- a/vnext/Scripts/rnw-dependencies.ps1 +++ b/vnext/Scripts/rnw-dependencies.ps1 @@ -6,7 +6,11 @@ $v = [System.Environment]::OSVersion.Version; if ($env:Agent_BuildDirectory) { $drive = (Resolve-Path $env:Agent_BuildDirectory).Drive } else { - $drive = (Resolve-Path $PSCommandPath).Drive + if ($PSCommandPath) { + $drive = (Resolve-Path $PSCommandPath).Drive + } else { + $drive = (Resolve-Path $env:SystemDrive).Drive + } } function CheckVS { @@ -122,9 +126,9 @@ if (!(IsElevated)) { $NeedsRerun = $false foreach ($req in $requirements) { - Write-Output "Checking $($req.Name)"; + Write-Host -NoNewline "Checking $($req.Name) "; if (!($req.Valid)) { - Write-Output "Requirement failed: $($req.Name)"; + Write-Host -ForegroundColor Red " Failed"; if ($req.Install) { if ($Install -or (!$NoPrompt -and (Read-Host "Do you want to install? ").ToUpperInvariant() -eq 'Y')) { Invoke-Command $req.Install -ErrorAction Stop @@ -135,6 +139,8 @@ foreach ($req in $requirements) } else { $NeedsRerun = !($req.Optional); } + } else { + Write-Host -ForegroundColor Green " OK"; } } From 5c024c0a5a204628c108ab6be7575333cbcda47a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 13 May 2020 21:29:43 +0000 Subject: [PATCH 19/33] Bump typescript from 3.8.3 to 3.9.2 (#4890) --- yarn.lock | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5c28f727177..578a5f9233a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6307,9 +6307,9 @@ eslint-plugin-react-native@3.8.1: eslint-plugin-react-native-globals "^0.1.1" eslint-plugin-react@7.19.0, eslint-plugin-react@^7.14.1: - version "7.19.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666" - integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ== + version "7.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz#f98712f0a5e57dfd3e5542ef0604b8739cd47be3" + integrity sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA== dependencies: array-includes "^3.1.1" doctrine "^2.1.0" @@ -6320,7 +6320,6 @@ eslint-plugin-react@7.19.0, eslint-plugin-react@^7.14.1: object.values "^1.1.1" prop-types "^15.7.2" resolve "^1.15.1" - semver "^6.3.0" string.prototype.matchall "^4.0.2" xregexp "^4.3.0" @@ -13420,9 +13419,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.5.3, typescript@^3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" - integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== + version "3.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9" + integrity sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw== typescript@~3.7.2: version "3.7.2" From a8cd1704446f0626be620271b719b5e2be64fdd6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 13 May 2020 21:29:58 +0000 Subject: [PATCH 20/33] Bump lerna from 3.20.2 to 3.21.0 (#4889) --- yarn.lock | 210 +++++++++++++++++++++++++++--------------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/yarn.lock b/yarn.lock index 578a5f9233a..6633ac2c3d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1722,14 +1722,14 @@ dependencies: core-js "^2.5.7" -"@lerna/add@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.20.0.tgz#bea7edf36fc93fb72ec34cb9ba854c48d4abf309" - integrity sha512-AnH1oRIEEg/VDa3SjYq4x1/UglEAvrZuV0WssHUMN81RTZgQk3we+Mv3qZNddrZ/fBcZu2IAdN/EQ3+ie2JxKQ== +"@lerna/add@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.21.0.tgz#27007bde71cc7b0a2969ab3c2f0ae41578b4577b" + integrity sha512-vhUXXF6SpufBE1EkNEXwz1VLW03f177G9uMOFMQkp6OJ30/PWg4Ekifuz9/3YfgB2/GH8Tu4Lk3O51P2Hskg/A== dependencies: "@evocateur/pacote" "^9.6.3" - "@lerna/bootstrap" "3.20.0" - "@lerna/command" "3.18.5" + "@lerna/bootstrap" "3.21.0" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/npm-conf" "3.16.0" "@lerna/validation-error" "3.13.0" @@ -1738,12 +1738,12 @@ p-map "^2.1.0" semver "^6.2.0" -"@lerna/bootstrap@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.20.0.tgz#635d71046830f208e851ab429a63da1747589e37" - integrity sha512-Wylullx3uthKE7r4izo09qeRGL20Y5yONlQEjPCfnbxCC2Elu+QcPu4RC6kqKQ7b+g7pdC3OOgcHZjngrwr5XQ== +"@lerna/bootstrap@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.21.0.tgz#bcd1b651be5b0970b20d8fae04c864548123aed6" + integrity sha512-mtNHlXpmvJn6JTu0KcuTTPl2jLsDNud0QacV/h++qsaKbhAaJr/FElNZ5s7MwZFUM3XaDmvWzHKaszeBMHIbBw== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/has-npm-version" "3.16.5" "@lerna/npm-install" "3.16.5" @@ -1767,13 +1767,13 @@ read-package-tree "^5.1.6" semver "^6.2.0" -"@lerna/changed@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.20.0.tgz#66b97ebd6c8f8d207152ee524a0791846a9097ae" - integrity sha512-+hzMFSldbRPulZ0vbKk6RD9f36gaH3Osjx34wrrZ62VB4pKmjyuS/rxVYkCA3viPLHoiIw2F8zHM5BdYoDSbjw== +"@lerna/changed@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.21.0.tgz#108e15f679bfe077af500f58248c634f1044ea0b" + integrity sha512-hzqoyf8MSHVjZp0gfJ7G8jaz+++mgXYiNs9iViQGA8JlN/dnWLI5sWDptEH3/B30Izo+fdVz0S0s7ydVE3pWIw== dependencies: "@lerna/collect-updates" "3.20.0" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/listable" "3.18.5" "@lerna/output" "3.13.0" @@ -1795,12 +1795,12 @@ execa "^1.0.0" strong-log-transformer "^2.0.0" -"@lerna/clean@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.20.0.tgz#ba777e373ddeae63e57860df75d47a9e5264c5b2" - integrity sha512-9ZdYrrjQvR5wNXmHfDsfjWjp0foOkCwKe3hrckTzkAeQA1ibyz5llGwz5e1AeFrV12e2/OLajVqYfe+qdkZUgg== +"@lerna/clean@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.21.0.tgz#c0b46b5300cc3dae2cda3bec14b803082da3856d" + integrity sha512-b/L9l+MDgE/7oGbrav6rG8RTQvRiZLO1zTcG17zgJAAuhlsPxJExMlh2DFwJEVi2les70vMhHfST3Ue1IMMjpg== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/prompt" "3.18.5" "@lerna/pulse-till-done" "3.13.0" @@ -1840,14 +1840,14 @@ npmlog "^4.1.2" slash "^2.0.0" -"@lerna/command@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.18.5.tgz#14c6d2454adbfd365f8027201523e6c289cd3cd9" - integrity sha512-36EnqR59yaTU4HrR1C9XDFti2jRx0BgpIUBeWn129LZZB8kAB3ov1/dJNa1KcNRKp91DncoKHLY99FZ6zTNpMQ== +"@lerna/command@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.21.0.tgz#9a2383759dc7b700dacfa8a22b2f3a6e190121f7" + integrity sha512-T2bu6R8R3KkH5YoCKdutKv123iUgUbW8efVjdGCDnCMthAQzoentOJfDeodBwn0P2OqCl3ohsiNVtSn9h78fyQ== dependencies: "@lerna/child-process" "3.16.5" "@lerna/package-graph" "3.18.5" - "@lerna/project" "3.18.0" + "@lerna/project" "3.21.0" "@lerna/validation-error" "3.13.0" "@lerna/write-log-file" "3.13.0" clone-deep "^4.0.1" @@ -1882,14 +1882,14 @@ fs-extra "^8.1.0" npmlog "^4.1.2" -"@lerna/create@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.18.5.tgz#11ac539f069248eaf7bc4c42e237784330f4fc47" - integrity sha512-cHpjocbpKmLopCuZFI7cKEM3E/QY8y+yC7VtZ4FQRSaLU8D8i2xXtXmYaP1GOlVNavji0iwoXjuNpnRMInIr2g== +"@lerna/create@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.21.0.tgz#e813832adf3488728b139e5a75c8b01b1372e62f" + integrity sha512-cRIopzKzE2vXJPmsiwCDMWo4Ct+KTmX3nvvkQLDoQNrrRK7w+3KQT3iiorbj1koD95RsVQA7mS2haWok9SIv0g== dependencies: "@evocateur/pacote" "^9.6.3" "@lerna/child-process" "3.16.5" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/npm-conf" "3.16.0" "@lerna/validation-error" "3.13.0" camelcase "^5.0.0" @@ -1914,23 +1914,23 @@ "@lerna/child-process" "3.16.5" npmlog "^4.1.2" -"@lerna/diff@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.18.5.tgz#e9e2cb882f84d5b84f0487c612137305f07accbc" - integrity sha512-u90lGs+B8DRA9Z/2xX4YaS3h9X6GbypmGV6ITzx9+1Ga12UWGTVlKaCXBgONMBjzJDzAQOK8qPTwLA57SeBLgA== +"@lerna/diff@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.21.0.tgz#e6df0d8b9916167ff5a49fcb02ac06424280a68d" + integrity sha512-5viTR33QV3S7O+bjruo1SaR40m7F2aUHJaDAC7fL9Ca6xji+aw1KFkpCtVlISS0G8vikUREGMJh+c/VMSc8Usw== dependencies: "@lerna/child-process" "3.16.5" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/validation-error" "3.13.0" npmlog "^4.1.2" -"@lerna/exec@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.20.0.tgz#29f0c01aee2340eb46f90706731fef2062a49639" - integrity sha512-pS1mmC7kzV668rHLWuv31ClngqeXjeHC8kJuM+W2D6IpUVMGQHLcCTYLudFgQsuKGVpl0DGNYG+sjLhAPiiu6A== +"@lerna/exec@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.21.0.tgz#17f07533893cb918a17b41bcc566dc437016db26" + integrity sha512-iLvDBrIE6rpdd4GIKTY9mkXyhwsJ2RvQdB9ZU+/NhR3okXfqKc6py/24tV111jqpXTtZUW6HNydT4dMao2hi1Q== dependencies: "@lerna/child-process" "3.16.5" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/profiler" "3.20.0" "@lerna/run-topologically" "3.18.5" @@ -2006,13 +2006,13 @@ "@lerna/child-process" "3.16.5" semver "^6.2.0" -"@lerna/import@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.18.5.tgz#a9c7d8601870729851293c10abd18b3707f7ba5e" - integrity sha512-PH0WVLEgp+ORyNKbGGwUcrueW89K3Iuk/DDCz8mFyG2IG09l/jOF0vzckEyGyz6PO5CMcz4TI1al/qnp3FrahQ== +"@lerna/import@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.21.0.tgz#87b08f2a2bfeeff7357c6fd8490e638d3cd5b32d" + integrity sha512-aISkL4XD0Dqf5asDaOZWu65jgj8fWUhuQseZWuQe3UfHxav69fTS2YLIngUfencaOSZVOcVCom28YCzp61YDxw== dependencies: "@lerna/child-process" "3.16.5" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/prompt" "3.18.5" "@lerna/pulse-till-done" "3.13.0" "@lerna/validation-error" "3.13.0" @@ -2020,43 +2020,43 @@ fs-extra "^8.1.0" p-map-series "^1.0.0" -"@lerna/info@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/info/-/info-3.20.0.tgz#3a5212f3029f2bc6255f9533bdf4bcb120ef329a" - integrity sha512-Rsz+KQF9mczbGUbPTrtOed1N0C+cA08Qz0eX/oI+NNjvsryZIju/o7uedG4I3P55MBiAioNrJI88fHH3eTgYug== +"@lerna/info@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/info/-/info-3.21.0.tgz#76696b676fdb0f35d48c83c63c1e32bb5e37814f" + integrity sha512-0XDqGYVBgWxUquFaIptW2bYSIu6jOs1BtkvRTWDDhw4zyEdp6q4eaMvqdSap1CG+7wM5jeLCi6z94wS0AuiuwA== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/output" "3.13.0" envinfo "^7.3.1" -"@lerna/init@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.18.5.tgz#86dd0b2b3290755a96975069b5cb007f775df9f5" - integrity sha512-oCwipWrha98EcJAHm8AGd2YFFLNI7AW9AWi0/LbClj1+XY9ah+uifXIgYGfTk63LbgophDd8936ZEpHMxBsbAg== +"@lerna/init@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.21.0.tgz#1e810934dc8bf4e5386c031041881d3b4096aa5c" + integrity sha512-6CM0z+EFUkFfurwdJCR+LQQF6MqHbYDCBPyhu/d086LRf58GtYZYj49J8mKG9ktayp/TOIxL/pKKjgLD8QBPOg== dependencies: "@lerna/child-process" "3.16.5" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" fs-extra "^8.1.0" p-map "^2.1.0" write-json-file "^3.2.0" -"@lerna/link@3.18.5": - version "3.18.5" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.18.5.tgz#f24347e4f0b71d54575bd37cfa1794bc8ee91b18" - integrity sha512-xTN3vktJpkT7Nqc3QkZRtHO4bT5NvuLMtKNIBDkks0HpGxC9PRyyqwOoCoh1yOGbrWIuDezhfMg3Qow+6I69IQ== +"@lerna/link@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.21.0.tgz#8be68ff0ccee104b174b5bbd606302c2f06e9d9b" + integrity sha512-tGu9GxrX7Ivs+Wl3w1+jrLi1nQ36kNI32dcOssij6bg0oZ2M2MDEFI9UF2gmoypTaN9uO5TSsjCFS7aR79HbdQ== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/package-graph" "3.18.5" "@lerna/symlink-dependencies" "3.17.0" p-map "^2.1.0" slash "^2.0.0" -"@lerna/list@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.20.0.tgz#7e67cc29c5cf661cfd097e8a7c2d3dcce7a81029" - integrity sha512-fXTicPrfioVnRzknyPawmYIVkzDRBaQqk9spejS1S3O1DOidkihK0xxNkr8HCVC0L22w6f92g83qWDp2BYRUbg== +"@lerna/list@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.21.0.tgz#42f76fafa56dea13b691ec8cab13832691d61da2" + integrity sha512-KehRjE83B1VaAbRRkRy6jLX1Cin8ltsrQ7FHf2bhwhRHK0S54YuA6LOoBnY/NtA8bHDX/Z+G5sMY78X30NS9tg== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/listable" "3.18.5" "@lerna/output" "3.13.0" @@ -2202,10 +2202,10 @@ npmlog "^4.1.2" upath "^1.2.0" -"@lerna/project@3.18.0": - version "3.18.0" - resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.18.0.tgz#56feee01daeb42c03cbdf0ed8a2a10cbce32f670" - integrity sha512-+LDwvdAp0BurOAWmeHE3uuticsq9hNxBI0+FMHiIai8jrygpJGahaQrBYWpwbshbQyVLeQgx3+YJdW2TbEdFWA== +"@lerna/project@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.21.0.tgz#5d784d2d10c561a00f20320bcdb040997c10502d" + integrity sha512-xT1mrpET2BF11CY32uypV2GPtPVm6Hgtha7D81GQP9iAitk9EccrdNjYGt5UBYASl4CIDXBRxwmTTVGfrCx82A== dependencies: "@lerna/package" "3.16.0" "@lerna/validation-error" "3.13.0" @@ -2228,10 +2228,10 @@ inquirer "^6.2.0" npmlog "^4.1.2" -"@lerna/publish@3.20.2": - version "3.20.2" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.20.2.tgz#a45d29813099b3249657ea913d0dc3f8ebc5cc2e" - integrity sha512-N7Y6PdhJ+tYQPdI1tZum8W25cDlTp4D6brvRacKZusweWexxaopbV8RprBaKexkEX/KIbncuADq7qjDBdQHzaA== +"@lerna/publish@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.21.0.tgz#0112393125f000484c3f50caba71a547f91bd7f4" + integrity sha512-JZ+ehZB9UCQ9nqH8Ld/Yqc/If++aK/7XIubkrB9sQ5hf2GeIbmI/BrJpMgLW/e9T5bKrUBZPUvoUN3daVipA5A== dependencies: "@evocateur/libnpmaccess" "^3.1.2" "@evocateur/npm-registry-fetch" "^4.0.0" @@ -2239,7 +2239,7 @@ "@lerna/check-working-tree" "3.16.5" "@lerna/child-process" "3.16.5" "@lerna/collect-updates" "3.20.0" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/describe-ref" "3.16.5" "@lerna/log-packed" "3.16.0" "@lerna/npm-conf" "3.16.0" @@ -2254,7 +2254,7 @@ "@lerna/run-lifecycle" "3.16.2" "@lerna/run-topologically" "3.18.5" "@lerna/validation-error" "3.13.0" - "@lerna/version" "3.20.2" + "@lerna/version" "3.21.0" figgy-pudding "^3.5.1" fs-extra "^8.1.0" npm-package-arg "^6.1.0" @@ -2317,12 +2317,12 @@ figgy-pudding "^3.5.1" p-queue "^4.0.0" -"@lerna/run@3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.20.0.tgz#a479f7c42bdf9ebabb3a1e5a2bdebb7a8d201151" - integrity sha512-9U3AqeaCeB7KsGS9oyKNp62s9vYoULg/B4cqXTKZkc+OKL6QOEjYHYVSBcMK9lUXrMjCjDIuDSX3PnTCPxQ2Dw== +"@lerna/run@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.21.0.tgz#2a35ec84979e4d6e42474fe148d32e5de1cac891" + integrity sha512-fJF68rT3veh+hkToFsBmUJ9MHc9yGXA7LSDvhziAojzOb0AI/jBDp6cEcDQyJ7dbnplba2Lj02IH61QUf9oW0Q== dependencies: - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/filter-options" "3.20.0" "@lerna/npm-run-script" "3.16.5" "@lerna/output" "3.13.0" @@ -2367,15 +2367,15 @@ dependencies: npmlog "^4.1.2" -"@lerna/version@3.20.2": - version "3.20.2" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.20.2.tgz#3709141c0f537741d9bc10cb24f56897bcb30428" - integrity sha512-ckBJMaBWc+xJen0cMyCE7W67QXLLrc0ELvigPIn8p609qkfNM0L0CF803MKxjVOldJAjw84b8ucNWZLvJagP/Q== +"@lerna/version@3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.21.0.tgz#5bcc3d2de9eb8f4db18efb0d88973f9a509eccc3" + integrity sha512-nIT3u43fCNj6uSMN1dRxFnF4GhmIiOEqSTkGSjrMU+8kHKwzOqS/6X6TOzklBmCyEZOpF/fLlGqH3BZHnwLDzQ== dependencies: "@lerna/check-working-tree" "3.16.5" "@lerna/child-process" "3.16.5" "@lerna/collect-updates" "3.20.0" - "@lerna/command" "3.18.5" + "@lerna/command" "3.21.0" "@lerna/conventional-commits" "3.18.5" "@lerna/github-client" "3.16.5" "@lerna/gitlab-client" "3.15.0" @@ -9019,26 +9019,26 @@ left-pad@^1.3.0: integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== lerna@^3.16.1: - version "3.20.2" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.20.2.tgz#abf84e73055fe84ee21b46e64baf37b496c24864" - integrity sha512-bjdL7hPLpU3Y8CBnw/1ys3ynQMUjiK6l9iDWnEGwFtDy48Xh5JboR9ZJwmKGCz9A/sarVVIGwf1tlRNKUG9etA== - dependencies: - "@lerna/add" "3.20.0" - "@lerna/bootstrap" "3.20.0" - "@lerna/changed" "3.20.0" - "@lerna/clean" "3.20.0" + version "3.21.0" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.21.0.tgz#c81a0f8df45c6b7c9d3fc9fdcd0f846aca2375c6" + integrity sha512-ux8yOwQEgIXOZVUfq+T8nVzPymL19vlIoPbysOP3YA4hcjKlqQIlsjI/1ugBe6b4MF7W4iV5vS3gH9cGqBBc1A== + dependencies: + "@lerna/add" "3.21.0" + "@lerna/bootstrap" "3.21.0" + "@lerna/changed" "3.21.0" + "@lerna/clean" "3.21.0" "@lerna/cli" "3.18.5" - "@lerna/create" "3.18.5" - "@lerna/diff" "3.18.5" - "@lerna/exec" "3.20.0" - "@lerna/import" "3.18.5" - "@lerna/info" "3.20.0" - "@lerna/init" "3.18.5" - "@lerna/link" "3.18.5" - "@lerna/list" "3.20.0" - "@lerna/publish" "3.20.2" - "@lerna/run" "3.20.0" - "@lerna/version" "3.20.2" + "@lerna/create" "3.21.0" + "@lerna/diff" "3.21.0" + "@lerna/exec" "3.21.0" + "@lerna/import" "3.21.0" + "@lerna/info" "3.21.0" + "@lerna/init" "3.21.0" + "@lerna/link" "3.21.0" + "@lerna/list" "3.21.0" + "@lerna/publish" "3.21.0" + "@lerna/run" "3.21.0" + "@lerna/version" "3.21.0" import-local "^2.0.0" npmlog "^4.1.2" From 904f7c0080511f264274b1db48b0774f813cb163 Mon Sep 17 00:00:00 2001 From: kmelmon <33470154+kmelmon@users.noreply.github.com> Date: Wed, 13 May 2020 15:09:23 -0700 Subject: [PATCH 21/33] BugFix: fix default tabindex stomping over acceptsKeyboardFocus (#4893) * Change files * revert dfc57fcf2504f57baab20f550b36a618eaa99e56 * set default tab index to -1, the hope is to be in line with xbox assumption * xbox doesn't seem to rely on this, changing default back to match xaml default --- ...-windows-2020-05-13-12-47-43-tabfocus-fix.json | 8 ++++++++ vnext/ReactUWP/Views/ControlViewManager.cpp | 12 +++--------- vnext/ReactUWP/Views/ViewViewManager.cpp | 15 ++++----------- 3 files changed, 15 insertions(+), 20 deletions(-) create mode 100644 change/react-native-windows-2020-05-13-12-47-43-tabfocus-fix.json diff --git a/change/react-native-windows-2020-05-13-12-47-43-tabfocus-fix.json b/change/react-native-windows-2020-05-13-12-47-43-tabfocus-fix.json new file mode 100644 index 00000000000..3832af20367 --- /dev/null +++ b/change/react-native-windows-2020-05-13-12-47-43-tabfocus-fix.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "revert dfc57fcf2504f57baab20f550b36a618eaa99e56", + "packageName": "react-native-windows", + "email": "kmelmon@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-13T19:47:43.325Z" +} diff --git a/vnext/ReactUWP/Views/ControlViewManager.cpp b/vnext/ReactUWP/Views/ControlViewManager.cpp index 0b26c602d03..e91cb4a0226 100644 --- a/vnext/ReactUWP/Views/ControlViewManager.cpp +++ b/vnext/ReactUWP/Views/ControlViewManager.cpp @@ -58,15 +58,9 @@ bool ControlViewManager::UpdateProperty( } else if (propertyName == "tabIndex") { if (propertyValue.isNumber()) { auto tabIndex = propertyValue.asDouble(); - if (tabIndex == static_cast(tabIndex)) { - if (tabIndex < 0) { - control.IsTabStop(false); - control.ClearValue(xaml::Controls::Control::TabIndexProperty()); - } else { - control.IsTabStop(true); - control.TabIndex(static_cast(tabIndex)); - } - } + if (tabIndex == static_cast(tabIndex)) + control.ClearValue(xaml::Controls::Control::TabIndexProperty()); + control.TabIndex(static_cast(tabIndex)); } else if (propertyValue.isNull()) { control.ClearValue(xaml::Controls::Control::TabIndexProperty()); } diff --git a/vnext/ReactUWP/Views/ViewViewManager.cpp b/vnext/ReactUWP/Views/ViewViewManager.cpp index efc490184a1..74b4efe12a8 100644 --- a/vnext/ReactUWP/Views/ViewViewManager.cpp +++ b/vnext/ReactUWP/Views/ViewViewManager.cpp @@ -87,15 +87,8 @@ class ViewShadowNode : public ShadowNodeBase { void TabIndex(int32_t tabIndex) { m_tabIndex = tabIndex; - if (IsControl()) { - if (tabIndex < 0) { - GetControl().IsTabStop(false); - GetControl().ClearValue(xaml::Controls::Control::TabIndexProperty()); - } else { - GetControl().IsTabStop(true); - GetControl().TabIndex(tabIndex); - } - } + if (IsControl()) + GetControl().TabIndex(m_tabIndex); } bool OnClick() { @@ -213,7 +206,7 @@ class ViewShadowNode : public ShadowNodeBase { bool m_enableFocusRing = true; bool m_onClick = false; - int32_t m_tabIndex = -1; + int32_t m_tabIndex = std::numeric_limits::max(); xaml::Controls::ContentControl::GotFocus_revoker m_contentControlGotFocusRevoker{}; xaml::Controls::ContentControl::LostFocus_revoker m_contentControlLostFocusRevoker{}; @@ -375,7 +368,7 @@ bool ViewViewManager::UpdateProperty( pViewShadowNode->TabIndex(static_cast(tabIndex)); } } else if (propertyValue.isNull()) { - pViewShadowNode->TabIndex(-1); + pViewShadowNode->TabIndex(std::numeric_limits::max()); } } else { ret = Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue); From 5b96a1fc16bd6dc5ffbd5d3e7c272989f1dd5f98 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 15:42:03 -0700 Subject: [PATCH 22/33] Update e2e testing doc with CI debugging info (#4897) * add instructions for CI debugging for e2e test app * point e2e readme to e2e testing doc --- docs/e2e-testing.md | 20 ++++++++++++++++++++ docs/img/e2e-artifacts.png | Bin 0 -> 94953 bytes docs/img/e2e-crashdumps.png | Bin 0 -> 109748 bytes docs/img/e2e-syms.png | Bin 0 -> 95206 bytes packages/E2ETest/README.md | 4 +++- 5 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 docs/img/e2e-artifacts.png create mode 100644 docs/img/e2e-crashdumps.png create mode 100644 docs/img/e2e-syms.png diff --git a/docs/e2e-testing.md b/docs/e2e-testing.md index 83407a939a9..bda97c8cf67 100644 --- a/docs/e2e-testing.md +++ b/docs/e2e-testing.md @@ -436,3 +436,23 @@ this.submitButton.click(); You can easily to use By(string) to locate a element which associated with testID in the app. It's recommended to define a `get` for each locator like above. + +## Debugging E2E Tests in CI +If you have access to the AzureDevOps pipeline you'll be able to see test failures and debug crashes. +Here are the artifacts that are produced during the build: +- error screenshots of the app when a test failed +- test run XML - this contains some information like the name of the wdio test that failed and the JS stack +- tree dump outputs - you can compare these to the masters to see if there is a the difference responsible for the test failing. +- crash dumps of the e2e test app (ReactUWPTestApp) + +You can access these by going to the AzureDevOps run for your PR and clicking on the artifacts link: + +![Artifacts](img/e2e-artifacts.png) + +Then you can access crash dumps under the `ReactUWPTestAppTreeDump\CrashDumps` folder. +![CrashDumps](img/e2e-crashdumps.png) + +You can get the symbols from the `appxsym` (just download it and rename it to `.zip`): +![SymbolsPackage](img/e2e-syms.png) + + The `ReactUWPTestAppTreeDump` folder will also contain any tree dump outputs that were produced that did not match the masters. \ No newline at end of file diff --git a/docs/img/e2e-artifacts.png b/docs/img/e2e-artifacts.png new file mode 100644 index 0000000000000000000000000000000000000000..d722dad25432389b0243df6fa911baa76d0e8cfa GIT binary patch literal 94953 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 literal 0 HcmV?d00001 diff --git a/docs/img/e2e-crashdumps.png b/docs/img/e2e-crashdumps.png new file mode 100644 index 0000000000000000000000000000000000000000..3cb5ddf764c12c5ae2310e114a221423f7cd8a8a GIT binary patch literal 109748 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

WlxMdocotTfJ9yH75U8Bb)08 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

#H)`g=3e6FPq4oeZk6LGfZK%L@DLE-(YE;H_ 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 KxvX*C2*}uK_xk6tm$q?dE;$69Ng;4gzGnFe> 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 US_x~@2f&x^H3O|84TrG*0gSP~VgLXD literal 0 HcmV?d00001 diff --git a/packages/E2ETest/README.md b/packages/E2ETest/README.md index 0cf38b0e805..9d4b5ead9fe 100644 --- a/packages/E2ETest/README.md +++ b/packages/E2ETest/README.md @@ -1,3 +1,5 @@ # E2ETest project -This package is not published, and is just used to verify a standalone app \ No newline at end of file +This package is not published, and is just used to verify a standalone app + +For information on how to run and debug this project, see [e2e-testing](https://github.com/microsoft/react-native-windows/blob/master/docs/e2e-testing.md). \ No newline at end of file From 525bbe2667b4ed5f98d5fdd937768f24a84e3548 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 15:46:51 -0700 Subject: [PATCH 23/33] Update rnw-dependencies (#4894) * don't exit the powershell session and pause for keyboard input if interactive * Change files --- ...tive-windows-2020-05-13-14-16-07-rnw-dep-dontexit.json | 8 ++++++++ vnext/Scripts/rnw-dependencies.ps1 | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 change/react-native-windows-2020-05-13-14-16-07-rnw-dep-dontexit.json diff --git a/change/react-native-windows-2020-05-13-14-16-07-rnw-dep-dontexit.json b/change/react-native-windows-2020-05-13-14-16-07-rnw-dep-dontexit.json new file mode 100644 index 00000000000..bf1bca20445 --- /dev/null +++ b/change/react-native-windows-2020-05-13-14-16-07-rnw-dep-dontexit.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "don't exit the powershell session and pause for keyboard input if interactive", + "packageName": "react-native-windows", + "email": "asklar@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-05-13T21:16:07.200Z" +} diff --git a/vnext/Scripts/rnw-dependencies.ps1 b/vnext/Scripts/rnw-dependencies.ps1 index d91ee41d40d..c274c09006f 100644 --- a/vnext/Scripts/rnw-dependencies.ps1 +++ b/vnext/Scripts/rnw-dependencies.ps1 @@ -145,9 +145,11 @@ foreach ($req in $requirements) } if ($NeedsRerun) { - Write-Output "Some dependencies are not met. Re-run with -Install to install them."; - exit 1; + Write-Error "Some dependencies are not met. Re-run with -Install to install them."; + if (!$NoPrompt) { + [System.Console]::ReadKey(); + } + throw; } else { Write-Output "All mandatory requirements met"; - exit 0; } From 117fab268da0ec1c129d9cf57081a3b29ea06d36 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 15:58:05 -0700 Subject: [PATCH 24/33] enable Switch (fixed 4596) --- packages/E2ETest/app/ControlStyleTestPage.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/E2ETest/app/ControlStyleTestPage.tsx b/packages/E2ETest/app/ControlStyleTestPage.tsx index 9e91fd263ba..f42b01b31a4 100644 --- a/packages/E2ETest/app/ControlStyleTestPage.tsx +++ b/packages/E2ETest/app/ControlStyleTestPage.tsx @@ -3,8 +3,7 @@ * Licensed under the MIT License. */ - // Bug:4596 Switch -import { /* Switch, */ CheckBox, TextInput, View, StyleSheet, Button } from 'react-native'; + import { Switch, CheckBox, TextInput, View, StyleSheet, Button } from 'react-native'; import { DatePicker, Picker } from 'react-native-windows'; import React, { useState } from 'react'; import { SHOWBORDER_ON_CONTROLSTYLE, TREE_DUMP_RESULT } from './Consts'; @@ -58,10 +57,8 @@ export function ControlStyleTestPage() { { - /* - // Bug:4596 Switch - */} + } Date: Sat, 9 May 2020 00:02:39 -0700 Subject: [PATCH 25/33] improve treedump capabilities --- .../TreeDumpControlViewManager.cs | 170 +------------ .../windows/TreeDumpLibrary/TreeDumpHelper.cs | 238 ++++++++++++++++++ .../TreeDumpLibrary/TreeDumpLibrary.csproj | 4 +- .../TreeDumpLibrary/VisualTreeDumper.cs | 99 +++++++- 4 files changed, 332 insertions(+), 179 deletions(-) create mode 100644 packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs index 1e12a33264b..fea206cd49f 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpControlViewManager.cs @@ -5,11 +5,8 @@ using Microsoft.ReactNative.Managed; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Threading.Tasks; using Windows.ApplicationModel.DataTransfer; -using Windows.Data.Json; using Windows.Storage; using Windows.UI.ViewManagement; using Windows.UI.Xaml; @@ -126,180 +123,25 @@ private async void dispatcherTimer_Tick(object sender, object e) m_timer.Stop(); if (VisualTreeHelper.GetParent(m_textBlock) != null) { - await MatchTreeDumpFromLayoutUpdateAsync(); - } - } - private DependencyObject FindChildWithMatchingUIAID(DependencyObject element) - { - string automationId = (string)element.GetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty); - if (automationId == m_uiaID) - { - return element; - } - int childrenCount = VisualTreeHelper.GetChildrenCount(element); - for (int i = 0; i < childrenCount; i++) - { - var result = FindChildWithMatchingUIAID(VisualTreeHelper.GetChild(element, i)); - if (result != null) - { - return result; - } - } - - return null; - } - - private async Task MatchTreeDumpFromLayoutUpdateAsync() - { - // First find root - DependencyObject current = m_textBlock; - DependencyObject parent = VisualTreeHelper.GetParent(current); - while (parent != null) - { - current = parent; - parent = VisualTreeHelper.GetParent(current); - } - - DependencyObject dumpRoot = current; - // if UIAID is passed in from test, find the matching child as the root to dump - if (m_uiaID != null) - { - var matchingNode = FindChildWithMatchingUIAID(current); - if (matchingNode != null) + var matchSuccessful = await TreeDumpHelper.MatchTreeDumpFromLayoutUpdateAsync(m_dumpID, m_uiaID, m_textBlock, m_additionalProperties, DumpTreeMode.Json, m_dumpExpectedText); + if (!matchSuccessful) { - dumpRoot = matchingNode; - } - } - - string dumpText = VisualTreeDumper.DumpTree(dumpRoot, m_textBlock /* exclude */ , m_additionalProperties, mode); - if (dumpText != m_dumpExpectedText) - { - await MatchDump(dumpText); - } - } - - private readonly DumpTreeMode mode = DumpTreeMode.Json; - - private async Task MatchDump(string dumpText) - { - StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{GetMasterFile()}"); - if (m_dumpExpectedText == null) - { - try - { - m_dumpExpectedText = await FileIO.ReadTextAsync(masterFile); - StorageFolder storageFolder = ApplicationData.Current.LocalFolder; - string copyFileName = GetMasterFile(); - var copyDumpFile = await storageFolder.CreateFileAsync(copyFileName, CreationCollisionOption.ReplaceExisting); - await FileIO.WriteTextAsync(copyDumpFile, m_dumpExpectedText); - } - catch (IOException) - { - UpdateResult(false /*matchDump*/ , "Tree dump master file not found in testapp package!"); - } - } + StorageFile outFile = await storageFolder.GetFileAsync(TreeDumpHelper.GetOutputFile(m_dumpID)); + StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{TreeDumpHelper.GetMasterFile(m_dumpID)}"); - if (!DumpsAreEqual(m_dumpExpectedText, dumpText)) - { - StorageFolder storageFolder = ApplicationData.Current.LocalFolder; - string fileName = GetOutputFile(); - try - { - StorageFile outFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); - await FileIO.WriteTextAsync(outFile, dumpText); UpdateResult(false /*matchDump*/ , $"Tree dump file does not match master at {masterFile.Path} - See output at {outFile.Path}", GetInlines(masterFile, outFile, m_textBlock)); } - catch (IOException) + else { - UpdateResult(false /*matchDump*/ , "Can't write dump output file:" + fileName); + UpdateResult(true /*matchDump*/ , ""); } - } - else - { - UpdateResult(true /*matchDump*/ , ""); - } - } - - private bool DumpsAreEqual(string dumpExpectedText, string dumpText) - { - if (mode == DumpTreeMode.Default) - { - return dumpExpectedText == dumpText; - } - else - { - JsonValue expected = JsonValue.Parse(dumpExpectedText); - JsonValue actual = JsonValue.Parse(dumpText); - return JsonComparesEqual(expected, actual); - } - } - private bool JsonComparesEqual(IJsonValue expected, IJsonValue actual) - { - if (expected.ValueType != actual.ValueType) - { - return false; - } - switch (expected.ValueType) - { - case JsonValueType.String: - if (expected.GetString() == actual.GetString()) - { - return true; - } - else { Debug.WriteLine($"Expected {expected.GetString()} got {actual.GetString()}"); return false; } - case JsonValueType.Number: - return expected.GetNumber() == actual.GetNumber(); - case JsonValueType.Boolean: - return expected.GetBoolean() == actual.GetBoolean(); - case JsonValueType.Null: - return true; - case JsonValueType.Array: - { - var ea = expected.GetArray(); - var aa = actual.GetArray(); - if (ea.Count != aa.Count) { return false; } - for (uint i = 0; i < ea.Count; i++) - { - if (!JsonComparesEqual(ea[(int)i], aa[(int)i])) - { - return false; - } - } - return true; - } - case JsonValueType.Object: - { - var eo = expected.GetObject(); - var ao = actual.GetObject(); - if (eo.Keys.Count != ao.Keys.Count) { return false; } - foreach (var key in eo.Keys) - { - if (!JsonComparesEqual(eo.GetNamedValue(key), ao.GetNamedValue(key))) - { - return false; - } - } - return true; - } - default: - throw new ArgumentException(); } } - private string GetOutputFile() - { - return "TreeDump\\" + m_dumpID + (mode == DumpTreeMode.Json ? ".json" : ".out"); - } - - private string GetMasterFile() - { - return "TreeDump\\masters\\" + m_dumpID + (mode == DumpTreeMode.Json ? ".json" : ".txt"); - } - private static IList GetInlines(StorageFile masterFile, StorageFile outFile, UIElement anchor) { Hyperlink masterLink = new Hyperlink(); diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs new file mode 100644 index 00000000000..55daeb7c57f --- /dev/null +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs @@ -0,0 +1,238 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Windows.Data.Json; +using Windows.Storage; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +namespace TreeDumpLibrary +{ + public static class TreeDumpHelper + { + + private static DependencyObject FindChildWithMatchingUIAID(DependencyObject element, string uiaId) + { + string automationId = (string)element.GetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty); + if (automationId == uiaId) + { + return element; + } + int childrenCount = VisualTreeHelper.GetChildrenCount(element); + for (int i = 0; i < childrenCount; i++) + { + var result = FindChildWithMatchingUIAID(VisualTreeHelper.GetChild(element, i), uiaId); + if (result != null) + { + return result; + } + } + + return null; + } + + internal static async Task MatchTreeDumpFromLayoutUpdateAsync(string dumpID, string uiaId, TextBlock textBlock, IList additionalProperties, DumpTreeMode mode, string dumpExpectedText) + { + // First find root + DependencyObject current = textBlock; + DependencyObject parent = VisualTreeHelper.GetParent(current); + while (parent != null) + { + current = parent; + parent = VisualTreeHelper.GetParent(current); + } + + DependencyObject dumpRoot = current; + // if UIAID is passed in from test, find the matching child as the root to dump + if (uiaId != null) + { + var matchingNode = FindChildWithMatchingUIAID(current, uiaId); + if (matchingNode != null) + { + dumpRoot = matchingNode; + } + } + + string dumpText = VisualTreeDumper.DumpTree(dumpRoot, textBlock /* exclude */, additionalProperties, mode); + if (dumpText != dumpExpectedText) + { + return await MatchDump(dumpText, dumpID); + } + return true; + } + + + internal static async Task MatchDump(string outputJson, string dumpID) + { + Debug.WriteLine($"master file = {Windows.ApplicationModel.Package.Current.InstalledLocation.Path}\\Assets\\{GetMasterFile(dumpID)}"); + StorageFolder storageFolder = ApplicationData.Current.LocalFolder; + string fileName = GetOutputFile(dumpID); + Debug.WriteLine($"output file = {storageFolder.Path + "\\" + fileName}"); + + StorageFile outFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); + await FileIO.WriteTextAsync(outFile, outputJson); + + StorageFile masterFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync($@"Assets\{GetMasterFile(dumpID)}"); + + string masterJson = await FileIO.ReadTextAsync(masterFile); + + if (!DumpsAreEqual(masterJson, outputJson)) + { + return false; + } + else + { + return true; + } + } + + public static bool DumpsAreEqual(string dumpExpectedText, string dumpText) + { + JsonValue expected = JsonValue.Parse(dumpExpectedText); + JsonValue actual = JsonValue.Parse(dumpText); + return JsonComparesEqual(expected, actual, "root"); + } + + static readonly double epsilon = 1.0; + + private static bool JsonComparesEqual(IJsonValue expected, IJsonValue actual, string keyName) + { + //const string anything = "‎"; + const string Anything = ""; + //System.Diagnostics.Debug.Assert(anything == Anything); + if (expected.ValueType == JsonValueType.String && Regex.Replace(expected.GetString(), @"\p{C}", "") == Anything) + { + Debug.WriteLine($"Skipping ignored value: {actual.ValueType} {actual}"); + return true; + } + //Debug.WriteLine($"keyname: {keyName} {expected.ValueType} {actual.ValueType}"); + if (expected.ValueType != actual.ValueType) + { + Debug.WriteLine($"Expected {expected} got {actual}"); + return false; + } + switch (expected.ValueType) + { + case JsonValueType.String: + if (expected.GetString() != actual.GetString()) + { + Debug.WriteLine($"string:Expected {expected.GetString()} got {actual.GetString()}"); + return false; + } + return true; + case JsonValueType.Number: + if (Math.Abs(expected.GetNumber() - actual.GetNumber()) > epsilon) + { + Debug.WriteLine($"number: {keyName} {expected.GetNumber()} {actual.GetNumber()}"); + return false; + } + return true; + case JsonValueType.Boolean: + return expected.GetBoolean() == actual.GetBoolean(); + case JsonValueType.Null: + return true; + case JsonValueType.Array: + { + var ea = expected.GetArray(); + var aa = actual.GetArray(); + if (!JsonCompareArray(ea, aa)) + { + Debug.WriteLine("in key " + keyName); + return false; + } + return true; + } + case JsonValueType.Object: + { + if (!JsonCompareObject(expected.GetObject(), actual.GetObject())) + { + Debug.WriteLine("in key " + keyName); + return false; + } + return true; + } + default: + throw new ArgumentException(); + } + } + + private static bool JsonCompareArray(JsonArray ea, JsonArray aa) + { + if (ea.Count != aa.Count) + { + Debug.WriteLine($"Array count expected {ea.Count} got {aa.Count}"); + return false; + } + for (int i = 0; i < ea.Count; i++) + { + var _e = ea[i]; + var _a = aa[i]; + if (!JsonComparesEqual(_e, _a, "array element")) + { + Debug.WriteLine($"Array element {i} expected {_e.ValueType} got {_a.ValueType}"); + return false; + } + } + return true; + } + + private static bool JsonCompareObject(JsonObject eo, JsonObject ao) + { + var evisible = true; + const string visibilityProperty = "Visibility"; + if (eo.Keys.Contains(visibilityProperty)) + { + evisible = eo[visibilityProperty].GetString() == "Visible"; + eo.Remove("Visibility"); + } + var avisible = true; + if (ao.Keys.Contains(visibilityProperty)) + { + avisible = ao[visibilityProperty].GetString() == "Visible"; + ao.Remove(visibilityProperty); + } + if (avisible != evisible) { return false; } + if (avisible == false) + { + // both are collapsed (or nonexistent) so don't compare children + ao.Remove("children"); + eo.Remove("children"); + } + + if (eo.Keys.Count != ao.Keys.Count) + { + Debug.WriteLine($"Expected {eo.Keys.Count} but got {ao.Keys.Count}"); + Debug.WriteLine(string.Join(", ", eo.Keys)); + Debug.WriteLine(string.Join(", ", ao.Keys)); + return false; + } + foreach (var key in eo.Keys) + { + JsonValue evalue = eo.GetNamedValue(key); + JsonValue avalue = ao.GetNamedValue(key); + if (!JsonComparesEqual(evalue, avalue, key)) + { + Debug.WriteLine($"Property {key} compared differently {evalue.ValueType} {avalue.ValueType}: expected {evalue} got {avalue}"); + return false; + } + } + return true; + } + + public static string GetOutputFile(string dumpID) + { + return "TreeDump\\" + dumpID + ".json"; + } + + public static string GetMasterFile(string dumpID) + { + return "TreeDump\\masters\\" + dumpID + ".json"; + } + } +} diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj index e8ca1d3675b..6d7628538f4 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpLibrary.csproj @@ -1,6 +1,5 @@  - + Debug @@ -112,6 +111,7 @@ + diff --git a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs index 32a43aa7bd2..69779488887 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs @@ -3,10 +3,15 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Windows.Data.Json; using Windows.Foundation; using Windows.UI.Xaml; +using Windows.UI.Xaml.Automation; using Windows.UI.Xaml.Media; namespace TreeDumpLibrary @@ -51,12 +56,15 @@ public override string ToString() public bool ShouldVisitPropertiesForNode(DependencyObject node) { - return (node as UIElement) != null; + var fe = node as FrameworkElement; + string[] excludedNames = new string[] { "VerticalScrollBar", "HorizontalScrollBar", "ScrollBarSeparator" }; + if (fe != null && excludedNames.Contains(fe.Name)) { return false; } + return true; } - public bool ShouldVisitProperty(PropertyInfo propertyInfo) + public bool ShouldVisitProperty(string propertyName) { - return _filter.ShouldVisitProperty(propertyInfo.Name); + return _filter.ShouldVisitProperty(propertyName); } public void VisitProperty(string propertyName, object value, bool isLast) @@ -88,6 +96,50 @@ public bool ShouldVisitPropertyValue(string propertyName, object value) } } + private static JsonObject FindElementByAutomationId(JsonObject obj, string automationId) + { + if (obj.Keys.Contains("AutomationId") && obj["AutomationId"].GetString() == automationId) + { + return obj; + } + if (obj.Keys.Contains("children")) + { + var array = obj.GetNamedArray("children"); + foreach (var i in array) + { + var element = FindElementByAutomationId(i.GetObject(), automationId); + if (element != null) + { + return element; + } + } + } + return null; + } + + public static IAsyncOperation DoesTreeDumpMatchForRNTester(DependencyObject root) + { + string json = DumpTree(root, null, new string[] { }, DumpTreeMode.Json); + try + { + var obj = JsonValue.Parse(json).GetObject(); + var element = FindElementByAutomationId(obj, "PageHeader"); + if (element == null) + { + return Task.Run(() => false).AsAsyncOperation(); + } + var value = element.GetNamedString("Text"); + var pageName = new Regex(@"[<|>]").Replace(value, ""); + var match = TreeDumpHelper.MatchDump(json, pageName); + return match.AsAsyncOperation(); + } + catch + { + Debug.WriteLine("JSON ERROR:\n" + json); + throw; + } + } + public static string DumpTree(DependencyObject root, DependencyObject excludedNode, IList additionalProperties, DumpTreeMode mode) { var propertyFilter = new DefaultFilter(); @@ -111,20 +163,26 @@ private static void WalkThroughProperties(DependencyObject node, Visitor visitor if (visitor.ShouldVisitPropertiesForNode(node)) { var properties = (from property in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) - where visitor.ShouldVisitProperty(property) && + where visitor.ShouldVisitProperty(property.Name) && visitor.ShouldVisitPropertyValue(property.Name, GetObjectProperty(node, property)) orderby property.Name select property).ToArray(); + var automationId = node.GetValue(AutomationProperties.AutomationIdProperty); for (int i = 0; i < properties.Length; i++) { var property = properties[i]; object value = null; value = GetObjectProperty(node, property); - bool isLast = (i == properties.Length - 1) && !hasChildren; + bool isLast = (i == properties.Length - 1) && !hasChildren && (automationId == null); visitor.VisitProperty(property.Name, value, isLast); } + + if (automationId != null) + { + visitor.VisitProperty("AutomationId", automationId, !hasChildren); + } } } @@ -143,24 +201,36 @@ private static object GetObjectProperty(DependencyObject node, PropertyInfo prop return value; } + private static DependencyObject[] GetChildren(DependencyObject node, Visitor visitor) + { + DependencyObject[] dos = new DependencyObject[VisualTreeHelper.GetChildrenCount(node)]; + for (int i = 0; i < dos.Length; i++) + { + dos[i] = VisualTreeHelper.GetChild(node, i); + } + return dos.Where((n) => visitor.ShouldVisitPropertiesForNode(n)).ToArray(); + } + private static void WalkThroughTree(DependencyObject node, DependencyObject excludedNode, Visitor visitor, bool isLast = true) { - if (node != null) + if (node != null && visitor.ShouldVisitPropertiesForNode(node)) { // Assume that if we have a UIElement, we'll have some properties - visitor.BeginVisitNode(node, node is UIElement); + var children = GetChildren(node, visitor); + bool hasProperties = node is UIElement || (children.Length > 0); + + visitor.BeginVisitNode(node, hasProperties); - var childrenCount = VisualTreeHelper.GetChildrenCount(node); - WalkThroughProperties(node, visitor, childrenCount != 0); - if (childrenCount != 0) + WalkThroughProperties(node, visitor, children.Length != 0); + if (children.Length != 0) { visitor.BeginChildren(); - for (int i = 0; i < childrenCount; i++) + for (int i = 0; i < children.Length; i++) { - var child = VisualTreeHelper.GetChild(node, i); + var child = children[i]; if (child != excludedNode) { - bool isLastChild = (i == childrenCount - 1); + bool isLastChild = (i == children.Length - 1); WalkThroughTree(child, excludedNode, visitor, isLastChild); } } @@ -194,6 +264,7 @@ public DefaultFilter() "Clip", "FlowDirection", "Name", + "Text" /*"ActualOffset" 19h1*/ }; } @@ -258,6 +329,8 @@ public string PropertyValueToString(string propertyName, object propertyObject) public static string Quote(string s) { + s = s.Replace('\t', ' ').Replace("\n", @"\n"); + s = Regex.Replace(s, @"\p{Cs}", ""); // remove surrogate pairs e.g. emojis return '"' + s.Replace("\"", "\\\"") + '"'; } } From 62b8ef2bf044e5651f703f48405505f7a9c2219b Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Sat, 9 May 2020 19:01:47 -0700 Subject: [PATCH 26/33] update masters --- .../masters/ControlStyleRegularBorder.json | 111 ++---------------- .../masters/ControlStyleRoundBorder.json | 111 ++---------------- .../Assets/TreeDump/masters/ImageRTL.json | 1 + .../TreeDump/masters/ImageWithBorder.json | 1 + .../ImageWithoutBorder-Subsequent.json | 1 + .../TreeDump/masters/ImageWithoutBorder.json | 1 + .../windows/TreeDumpLibrary/TreeDumpHelper.cs | 2 - 7 files changed, 26 insertions(+), 202 deletions(-) diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json index 818fa573d29..6442cc408f4 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, + "AutomationId": "ControlStyleView", "children": [ { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", @@ -113,6 +114,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [20, 16], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -157,6 +159,7 @@ "Margin": "0,0,0,0", "Padding": "10,10,10,10", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, @@ -283,56 +286,6 @@ "RenderSize": [798, 48], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -350,6 +303,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [798, 48], + "Text": "TextBox", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -531,56 +485,6 @@ "RenderSize": [798, 48], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -598,6 +502,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [798, 48], + "Text": "Password", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -699,6 +604,7 @@ "Name": "DateText", "Padding": "12,0,0,2", "RenderSize": [90, 21], + "Text": "select a date", "VerticalAlignment": "Center", "Visibility": "Visible" }, @@ -738,6 +644,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -780,6 +687,7 @@ "Margin": "0,0,0,0", "Padding": "12,5,0,7", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Top", "Visibility": "Visible", "Width": 800, @@ -859,6 +767,7 @@ "Name": "PlaceholderTextBlock", "Padding": "0,0,0,0", "RenderSize": [756, 19], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible" } @@ -878,6 +787,7 @@ "Name": "EditableText", "Padding": "11,5,32,6", "RenderSize": [0, 0], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Collapsed" }, @@ -934,6 +844,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json index 3e26498c954..398d7cb8609 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, + "AutomationId": "ControlStyleView", "children": [ { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", @@ -113,6 +114,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [20, 16], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -157,6 +159,7 @@ "Margin": "0,0,0,0", "Padding": "10,10,10,10", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, @@ -283,56 +286,6 @@ "RenderSize": [780, 30], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -350,6 +303,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [780, 39], + "Text": "TextBox", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -531,56 +485,6 @@ "RenderSize": [780, 30], "VerticalAlignment": "Stretch", "Visibility": "Visible" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Right", - "Margin": "0,0,0,0", - "Name": "VerticalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Primitives.ScrollBar", - "Background": "#00FFFFFF", - "BorderBrush": "#00FFFFFF", - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "2,2,2,2", - "FlowDirection": "LeftToRight", - "Foreground": "#00FFFFFF", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "HorizontalScrollBar", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" - }, - { - "XamlType": "Windows.UI.Xaml.Controls.Border", - "Background": "#FFE6E6E6", - "BorderBrush": null, - "BorderThickness": "0,0,0,0", - "Clip": null, - "CornerRadius": "0,0,0,0", - "FlowDirection": "LeftToRight", - "HorizontalAlignment": "Stretch", - "Margin": "0,0,0,0", - "Name": "ScrollBarSeparator", - "Padding": "0,0,0,0", - "RenderSize": [0, 0], - "VerticalAlignment": "Stretch", - "Visibility": "Collapsed" } ] } @@ -598,6 +502,7 @@ "Name": "PlaceholderTextContentPresenter", "Padding": "10,10,10,10", "RenderSize": [780, 39], + "Text": "Password", "VerticalAlignment": "Stretch", "Visibility": "Visible" }, @@ -699,6 +604,7 @@ "Name": "DateText", "Padding": "12,0,0,2", "RenderSize": [90, 21], + "Text": "select a date", "VerticalAlignment": "Center", "Visibility": "Visible" }, @@ -738,6 +644,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } @@ -780,6 +687,7 @@ "Margin": "0,0,0,0", "Padding": "12,5,0,7", "RenderSize": [800, 50], + "Text": "", "VerticalAlignment": "Top", "Visibility": "Visible", "Width": 800, @@ -859,6 +767,7 @@ "Name": "PlaceholderTextBlock", "Padding": "0,0,0,0", "RenderSize": [756, 19], + "Text": "", "VerticalAlignment": "Stretch", "Visibility": "Visible" } @@ -878,6 +787,7 @@ "Name": "EditableText", "Padding": "11,5,32,6", "RenderSize": [0, 0], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Collapsed" }, @@ -934,6 +844,7 @@ "Margin": "0,0,0,0", "Padding": "0,0,0,0", "RenderSize": [12, 12], + "Text": "", "VerticalAlignment": "Center", "Visibility": "Visible" } diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json index c00ab2049da..e6560044fe8 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageRTL.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json index 753214da826..9c87e39efe5 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithBorder.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json index c00ab2049da..e6560044fe8 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder-Subsequent.json @@ -14,6 +14,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Microsoft.ReactNative.ViewPanel", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json index 9406a02556a..9be2fa56439 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ImageWithoutBorder.json @@ -13,6 +13,7 @@ "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 500, + "AutomationId": "ImageContainer", "children": [ { "XamlType": "Windows.UI.Xaml.DependencyObject" diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs index 55daeb7c57f..e2d60587cc9 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs @@ -103,9 +103,7 @@ public static bool DumpsAreEqual(string dumpExpectedText, string dumpText) private static bool JsonComparesEqual(IJsonValue expected, IJsonValue actual, string keyName) { - //const string anything = "‎"; const string Anything = ""; - //System.Diagnostics.Debug.Assert(anything == Anything); if (expected.ValueType == JsonValueType.String && Regex.Replace(expected.GetString(), @"\p{C}", "") == Anything) { Debug.WriteLine($"Skipping ignored value: {actual.ValueType} {actual}"); From f7a7fe434374bb3f73b7a8686c19bc501fa5077f Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 15:58:05 -0700 Subject: [PATCH 27/33] enable Switch (fixed 4596) --- packages/E2ETest/app/ControlStyleTestPage.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/E2ETest/app/ControlStyleTestPage.tsx b/packages/E2ETest/app/ControlStyleTestPage.tsx index 9e91fd263ba..f42b01b31a4 100644 --- a/packages/E2ETest/app/ControlStyleTestPage.tsx +++ b/packages/E2ETest/app/ControlStyleTestPage.tsx @@ -3,8 +3,7 @@ * Licensed under the MIT License. */ - // Bug:4596 Switch -import { /* Switch, */ CheckBox, TextInput, View, StyleSheet, Button } from 'react-native'; + import { Switch, CheckBox, TextInput, View, StyleSheet, Button } from 'react-native'; import { DatePicker, Picker } from 'react-native-windows'; import React, { useState } from 'react'; import { SHOWBORDER_ON_CONTROLSTYLE, TREE_DUMP_RESULT } from './Consts'; @@ -58,10 +57,8 @@ export function ControlStyleTestPage() { { - /* - // Bug:4596 Switch - */} + } Date: Wed, 13 May 2020 16:29:49 -0700 Subject: [PATCH 28/33] protect against exceptions in run_wdio --- packages/E2ETest/run_wdio.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/E2ETest/run_wdio.js b/packages/E2ETest/run_wdio.js index aec747f94f2..2872b1fed55 100644 --- a/packages/E2ETest/run_wdio.js +++ b/packages/E2ETest/run_wdio.js @@ -153,4 +153,10 @@ function runWdio() { ); } -runWdio(); +try { + runWdio(); +} catch (e) { + console.log(e); + // any exception that isn't handled is an error + process.exit(2); +} From a52a9b043a2977047be47d1f8a984bc3c41cc204 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 16:57:57 -0700 Subject: [PATCH 29/33] add another try block --- packages/E2ETest/run_wdio.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/E2ETest/run_wdio.js b/packages/E2ETest/run_wdio.js index 2872b1fed55..d16d00842dc 100644 --- a/packages/E2ETest/run_wdio.js +++ b/packages/E2ETest/run_wdio.js @@ -144,7 +144,13 @@ function runWdio() { wdio.run().then( code => { - doProcess(code); + try { + doProcess(code); + } catch (e) { + console.log(e); + // any exception that isn't handled is an error + process.exit(3); + } }, error => { console.error('Launcher failed to start the test', error.stacktrace); From b05376dd911c8e965458c2df0853489be4241a9f Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 17:35:02 -0700 Subject: [PATCH 30/33] update e2e testing and masters, fixes 4680 --- docs/e2e-testing.md | 33 +++ docs/img/e2e-errors.png | Bin 0 -> 67545 bytes .../masters/ControlStyleRegularBorder.json | 226 +++++++++++++++++- .../masters/ControlStyleRoundBorder.json | 226 +++++++++++++++++- 4 files changed, 481 insertions(+), 4 deletions(-) create mode 100644 docs/img/e2e-errors.png diff --git a/docs/e2e-testing.md b/docs/e2e-testing.md index bda97c8cf67..986a4e5f268 100644 --- a/docs/e2e-testing.md +++ b/docs/e2e-testing.md @@ -437,6 +437,39 @@ You can easily to use By(string) to locate a element which associated with testI It's recommended to define a `get` for each locator like above. +## E2E Tests and masters + +E2E tests can be summarized as follows: +- they are tests that run the ReactUWPTestApp +- use UI Automation to navigate between pages, query the state of elements, click on them, etc. +- the ReactUWPTestApp has code to produce a dump of the its own visual tree ("tree dump output") and compares it with a checked in copy ("tree dump masters") to make sure nothing has regressed. The tree dumps are produced in Json format (there is also an option to produce them in a custom text format of key=value, but that is deprecated now). + +So you've added or updated some tests: great! you get a cookie*. But now you probably need to update the masters, or the tests will fail and break the CI. +The best way to do this is by letting the CI run and fail, then downloading the generated tree dump output files, and comparing to the masters. Make sure the differences are expected, copy over them and check them in. The reason is that the masters will include things like the size elements rendered at, which can be dependent on DPI, scale factor, resolution, and in some cases (due to bugs) even differ based on bitness (see #4628). + +When an output doesn't match its master, a file with `.err` extension will be produced under the `TreeDump` folder in the `ReactUWPTestAppTreeDump` artifact. The content of the `.err` file will usually just say: + +```txt +Tree dump file does not match master at C:\Program Files\WindowsApps\ReactUWPTestApp_1.0.0.0_x64__kc2bncckyf4ap\Assets\TreeDump\masters\ControlStyleRoundBorder.json - See output at C:\Users\VssAdministrator\AppData\Local\Packages\ReactUWPTestApp_kc2bncckyf4ap\LocalState\TreeDump\ControlStyleRoundBorder.json +``` + +![Errors](img/e2e-errors.png) + +Find the corresponding `.json` file in that folder and compare it to its master. The masters live in [e2etest\windows\ReactUWPTestApp\Assets\TreeDump\masters](https://github.com/microsoft/react-native-windows/tree/master/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters). + +Sometimes you'll have an element in your test that produces output that should not be used for comparison. You can manually edit the generated json and set the output that you want to ignore to the `` value: + +```json +... +"Windows.UI.Xaml.Button": +{ + "Text": "", + ... +} +... +``` + + ## Debugging E2E Tests in CI If you have access to the AzureDevOps pipeline you'll be able to see test failures and debug crashes. Here are the artifacts that are produced during the build: diff --git a/docs/img/e2e-errors.png b/docs/img/e2e-errors.png new file mode 100644 index 0000000000000000000000000000000000000000..6a49cbd1d5bd12b463f58368c8b7b6c64643a5e8 GIT binary patch literal 67545 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 ag7M>-l{kNqo94=RTs38FrA&ph0sjY=#XAxJ literal 0 HcmV?d00001 diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json index 6442cc408f4..b6b323e4662 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRegularBorder.json @@ -6,15 +6,237 @@ "Clip": null, "CornerRadius": "0,0,0,0", "FlowDirection": "LeftToRight", - "Height": 300, + "Height": 360, "HorizontalAlignment": "Stretch", "Margin": "0,0,0,0", - "RenderSize": [800, 300], + "RenderSize": [800, 360], "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, "AutomationId": "ControlStyleView", "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.ToggleSwitch", + "Background": "#33E1E1E1", + "BorderBrush": "#55FF00FF", + "BorderThickness": "1,1,1,1", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#FFFFFFFF", + "Height": 50, + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [51, 50], + "VerticalAlignment": "Center", + "Visibility": "Visible", + "Width": 51, + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": "#33E1E1E1", + "BorderBrush": "#55FF00FF", + "BorderThickness": "1,1,1,1", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [51, 50], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#66000000", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "HeaderContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Top", + "Visibility": "Collapsed" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [154, 32], + "VerticalAlignment": "Top", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": "#00FFFFFF", + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,5,0,5", + "Name": "SwitchAreaGrid", + "Padding": "0,0,0,0", + "RenderSize": [52, 22], + "VerticalAlignment": "Stretch", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#FFFFFFFF", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "OffContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Center", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#FFFFFFFF", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "OnContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Center", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "OuterBorder", + "RenderSize": [40, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 40 + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobBounds", + "RenderSize": [40, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 40 + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "SwitchKnob", + "Padding": "0,0,0,0", + "RenderSize": [20, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 20, + "children": [ + { + "XamlType": "Windows.UI.Xaml.Shapes.Ellipse", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 10, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobOn", + "RenderSize": [10, 10], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 10 + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Ellipse", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 10, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobOff", + "RenderSize": [10, 10], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 10 + } + ] + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Primitives.Thumb", + "Background": "#33000000", + "BorderBrush": "#00FFFFFF", + "BorderThickness": "1,1,1,1", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#FFFFFFFF", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchThumb", + "Padding": "0,0,0,0", + "RenderSize": [52, 32], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "RenderSize": [52, 32], + "VerticalAlignment": "Stretch", + "Visibility": "Visible" + } + ] + } + ] + } + ] + } + ] + }, { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", "Background": "#33E1E1E1", diff --git a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json index 398d7cb8609..a236fcc7778 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json +++ b/packages/E2ETest/windows/ReactUWPTestApp/Assets/TreeDump/masters/ControlStyleRoundBorder.json @@ -6,15 +6,237 @@ "Clip": null, "CornerRadius": "0,0,0,0", "FlowDirection": "LeftToRight", - "Height": 300, + "Height": 360, "HorizontalAlignment": "Stretch", "Margin": "0,0,0,0", - "RenderSize": [800, 300], + "RenderSize": [800, 360], "VerticalAlignment": "Stretch", "Visibility": "Visible", "Width": 800, "AutomationId": "ControlStyleView", "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.ToggleSwitch", + "Background": "#33000000", + "BorderBrush": "#5500FF00", + "BorderThickness": "10,10,10,10", + "Clip": null, + "CornerRadius": "10,10,10,10", + "FlowDirection": "LeftToRight", + "Foreground": "#FF000000", + "Height": 50, + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [51, 50], + "VerticalAlignment": "Center", + "Visibility": "Visible", + "Width": 51, + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": "#33000000", + "BorderBrush": "#5500FF00", + "BorderThickness": "10,10,10,10", + "Clip": null, + "CornerRadius": "10,10,10,10", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [51, 50], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#66000000", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "HeaderContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Top", + "Visibility": "Collapsed" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Padding": "0,0,0,0", + "RenderSize": [154, 32], + "VerticalAlignment": "Top", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": "#00FFFFFF", + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,5,0,5", + "Name": "SwitchAreaGrid", + "Padding": "0,0,0,0", + "RenderSize": [52, 22], + "VerticalAlignment": "Stretch", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#66000000", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "OffContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Center", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Controls.ContentPresenter", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#66000000", + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "OnContentPresenter", + "Padding": "0,0,0,0", + "RenderSize": [0, 0], + "VerticalAlignment": "Center", + "Visibility": "Visible" + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "OuterBorder", + "RenderSize": [40, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 40 + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobBounds", + "RenderSize": [40, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 40 + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Grid", + "Background": null, + "BorderBrush": null, + "BorderThickness": "0,0,0,0", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Height": 20, + "HorizontalAlignment": "Left", + "Margin": "0,0,0,0", + "Name": "SwitchKnob", + "Padding": "0,0,0,0", + "RenderSize": [20, 20], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 20, + "children": [ + { + "XamlType": "Windows.UI.Xaml.Shapes.Ellipse", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 10, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobOn", + "RenderSize": [10, 10], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 10 + }, + { + "XamlType": "Windows.UI.Xaml.Shapes.Ellipse", + "Clip": null, + "FlowDirection": "LeftToRight", + "Height": 10, + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchKnobOff", + "RenderSize": [10, 10], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "Width": 10 + } + ] + }, + { + "XamlType": "Windows.UI.Xaml.Controls.Primitives.Thumb", + "Background": "#33000000", + "BorderBrush": "#00FFFFFF", + "BorderThickness": "1,1,1,1", + "Clip": null, + "CornerRadius": "0,0,0,0", + "FlowDirection": "LeftToRight", + "Foreground": "#FF000000", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "Name": "SwitchThumb", + "Padding": "0,0,0,0", + "RenderSize": [52, 32], + "VerticalAlignment": "Stretch", + "Visibility": "Visible", + "children": [ + { + "XamlType": "Windows.UI.Xaml.Shapes.Rectangle", + "Clip": null, + "FlowDirection": "LeftToRight", + "HorizontalAlignment": "Stretch", + "Margin": "0,0,0,0", + "RenderSize": [52, 32], + "VerticalAlignment": "Stretch", + "Visibility": "Visible" + } + ] + } + ] + } + ] + } + ] + }, { "XamlType": "Windows.UI.Xaml.Controls.CheckBox", "Background": "#33000000", From 01f22e824c377fd56da317aa8a60d3af066d358b Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 18:51:44 -0700 Subject: [PATCH 31/33] publish wdio report and fix run_wdio typo bug --- .ado/templates/e2e-test-job.yml | 7 +++++++ packages/E2ETest/run_wdio.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.ado/templates/e2e-test-job.yml b/.ado/templates/e2e-test-job.yml index 2dfe9f642a6..7f073952b61 100644 --- a/.ado/templates/e2e-test-job.yml +++ b/.ado/templates/e2e-test-job.yml @@ -91,6 +91,13 @@ jobs: script: yarn run e2etest workingDirectory: packages/E2ETest + - task: CopyFiles@2 + displayName: Copy test report + inputs: + sourceFolder: $(Build.SourcesDirectory)\packages\E2ETest\reports + targetFolder: $(Build.StagingDirectory)/ReactUWPTestAppTreeDump/reports + condition: succeededOrFailed() + - task: CopyFiles@2 displayName: Copy tree dump output files inputs: diff --git a/packages/E2ETest/run_wdio.js b/packages/E2ETest/run_wdio.js index d16d00842dc..c99672ac5c3 100644 --- a/packages/E2ETest/run_wdio.js +++ b/packages/E2ETest/run_wdio.js @@ -88,7 +88,7 @@ function parseLog(logfile) { const name = attr.name; failures[name] = {}; - for (const testcase of testsuite.testcases) { + for (const testcase of testsuite.testcase) { if (testcase.error && testcase.error[0].ATTR) { failures[name].testcase = testcase.ATTR.name; failures[name].error = testcase.error[0].ATTR.message; From 608f1f1712acedd3b5cf69706b90bdd58890eb3b Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Wed, 13 May 2020 21:52:53 -0700 Subject: [PATCH 32/33] TreeDump should ignore collapsed object elements in an array --- docs/e2e-testing.md | 3 ++ docs/img/e2e-testfail.png | Bin 0 -> 135574 bytes packages/E2ETest/run_wdio.js | 2 +- .../windows/TreeDumpLibrary/TreeDumpHelper.cs | 29 +++++++++++++----- .../TreeDumpLibrary/VisualTreeDumper.cs | 4 ++- 5 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 docs/img/e2e-testfail.png diff --git a/docs/e2e-testing.md b/docs/e2e-testing.md index 986a4e5f268..a126a8b76bb 100644 --- a/docs/e2e-testing.md +++ b/docs/e2e-testing.md @@ -445,6 +445,9 @@ E2E tests can be summarized as follows: - the ReactUWPTestApp has code to produce a dump of the its own visual tree ("tree dump output") and compares it with a checked in copy ("tree dump masters") to make sure nothing has regressed. The tree dumps are produced in Json format (there is also an option to produce them in a custom text format of key=value, but that is deprecated now). So you've added or updated some tests: great! you get a cookie*. But now you probably need to update the masters, or the tests will fail and break the CI. + +![testFail](img/e2e-testfail.png) + The best way to do this is by letting the CI run and fail, then downloading the generated tree dump output files, and comparing to the masters. Make sure the differences are expected, copy over them and check them in. The reason is that the masters will include things like the size elements rendered at, which can be dependent on DPI, scale factor, resolution, and in some cases (due to bugs) even differ based on bitness (see #4628). When an output doesn't match its master, a file with `.err` extension will be produced under the `TreeDump` folder in the `ReactUWPTestAppTreeDump` artifact. The content of the `.err` file will usually just say: diff --git a/docs/img/e2e-testfail.png b/docs/img/e2e-testfail.png new file mode 100644 index 0000000000000000000000000000000000000000..5ceadb196d2f4f859896a993877b7464bb81f8e1 GIT binary patch literal 135574 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

M?hT4I*-FMcfW4YlsN(f3>7N^#PS#*QlkNRx5 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

Bfdy5D9)-@^7-f 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 x.endsWith('.log')); const names = logs .map(x => parseLog(path.join(reportsDir, x))) - .filter(x => x != null); + .filter(x => x != null && x != ''); return names; } diff --git a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs index e2d60587cc9..ec75dde5154 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/TreeDumpHelper.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Windows.Data.Json; @@ -162,15 +163,18 @@ private static bool JsonComparesEqual(IJsonValue expected, IJsonValue actual, st private static bool JsonCompareArray(JsonArray ea, JsonArray aa) { - if (ea.Count != aa.Count) + var efiltered = ea.Where(x => IsNonCollapsed(x)).ToArray(); + var afiltered = aa.Where(x => IsNonCollapsed(x)).ToArray(); + + if (efiltered.Length != afiltered.Length) { Debug.WriteLine($"Array count expected {ea.Count} got {aa.Count}"); return false; } - for (int i = 0; i < ea.Count; i++) + for (int i = 0; i < efiltered.Length; i++) { - var _e = ea[i]; - var _a = aa[i]; + var _e = efiltered[i]; + var _a = afiltered[i]; if (!JsonComparesEqual(_e, _a, "array element")) { Debug.WriteLine($"Array element {i} expected {_e.ValueType} got {_a.ValueType}"); @@ -180,19 +184,28 @@ private static bool JsonCompareArray(JsonArray ea, JsonArray aa) return true; } + private const string visibilityProperty = "Visibility"; + private const string visibilityPropertyVisible = "Visible"; + + private static bool IsNonCollapsed(IJsonValue x) + { + return x.ValueType != JsonValueType.Object || + !x.GetObject().ContainsKey(visibilityProperty) || + x.GetObject().GetNamedString(visibilityProperty) == visibilityPropertyVisible; + } + private static bool JsonCompareObject(JsonObject eo, JsonObject ao) { var evisible = true; - const string visibilityProperty = "Visibility"; if (eo.Keys.Contains(visibilityProperty)) { - evisible = eo[visibilityProperty].GetString() == "Visible"; - eo.Remove("Visibility"); + evisible = eo[visibilityProperty].GetString() == visibilityPropertyVisible; + eo.Remove(visibilityProperty); } var avisible = true; if (ao.Keys.Contains(visibilityProperty)) { - avisible = ao[visibilityProperty].GetString() == "Visible"; + avisible = ao[visibilityProperty].GetString() == visibilityPropertyVisible; ao.Remove(visibilityProperty); } if (avisible != evisible) { return false; } diff --git a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs index 69779488887..fd95352ebb4 100644 --- a/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs +++ b/packages/E2ETest/windows/TreeDumpLibrary/VisualTreeDumper.cs @@ -322,7 +322,9 @@ public string PropertyValueToString(string propertyName, object propertyObject) { // comparing doubles is numerically unstable so just compare their integer parts Size size = (Size)propertyObject; - return $"[{(int)size.Width}, {(int)size.Height}]"; + int width = (int)size.Width; + int height = (int)size.Height; + return $"[{width}, {height}]"; } return Quote(propertyObject.ToString()); } From 495d790bed34336f673201177936d494c5a90576 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Thu, 14 May 2020 00:35:10 -0700 Subject: [PATCH 33/33] add info about run_wdio --- docs/e2e-testing.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/e2e-testing.md b/docs/e2e-testing.md index a126a8b76bb..4fc59c96901 100644 --- a/docs/e2e-testing.md +++ b/docs/e2e-testing.md @@ -446,6 +446,8 @@ E2E tests can be summarized as follows: So you've added or updated some tests: great! you get a cookie*. But now you probably need to update the masters, or the tests will fail and break the CI. +\* void where prohibited, prizes and participation may vary. + ![testFail](img/e2e-testfail.png) The best way to do this is by letting the CI run and fail, then downloading the generated tree dump output files, and comparing to the masters. Make sure the differences are expected, copy over them and check them in. The reason is that the masters will include things like the size elements rendered at, which can be dependent on DPI, scale factor, resolution, and in some cases (due to bugs) even differ based on bitness (see #4628). @@ -472,6 +474,17 @@ Sometimes you'll have an element in your test that produces output that should n ... ``` +## run_wdio + +WDIO is not really built to be run within Azure DevOps, so I wrote a utility called `run_wdio` to adapt it to something that can run in ADO. +It can be found in [\packages\e2etest\run_wdio.js](https://github.com/microsoft/react-native-windows/blob/master/packages/E2ETest/run_wdio.js) +Its main features (which WDIO lacks) are: + +* reports success/failure to ADO so that test failures will break the CI +* supports test selection on the command line +* supports test metadata and filtering (e.g. you can mark a test as "do not run in the lab") +* prints out the list of tests and test cases that failed in the CI console + ## Debugging E2E Tests in CI If you have access to the AzureDevOps pipeline you'll be able to see test failures and debug crashes.

7A|`YzB^O&H9Utboj8WNNygwF_l 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