diff --git a/src/common/UITestAutomation/Element/Element.cs b/src/common/UITestAutomation/Element/Element.cs index 6414810072..4790a0af20 100644 --- a/src/common/UITestAutomation/Element/Element.cs +++ b/src/common/UITestAutomation/Element/Element.cs @@ -157,7 +157,7 @@ namespace Microsoft.PowerToys.UITest /// The selector to use for finding the element. /// The timeout in milliseconds. /// The found element. - public T Find(By by, int timeoutMS = 3000) + public T Find(By by, int timeoutMS = 5000) where T : Element, new() { Assert.IsNotNull(this.windowsElement, $"WindowsElement is null in method Find<{typeof(T).Name}> with parameters: by = {by}, timeoutMS = {timeoutMS}"); @@ -178,7 +178,7 @@ namespace Microsoft.PowerToys.UITest /// The name for finding the element. /// The timeout in milliseconds. /// The found element. - public T Find(string name, int timeoutMS = 3000) + public T Find(string name, int timeoutMS = 5000) where T : Element, new() { return this.Find(By.Name(name), timeoutMS); @@ -191,7 +191,7 @@ namespace Microsoft.PowerToys.UITest /// The selector to use for finding the element. /// The timeout in milliseconds. /// The found element. - public Element Find(By by, int timeoutMS = 3000) + public Element Find(By by, int timeoutMS = 5000) { return this.Find(by, timeoutMS); } @@ -203,7 +203,7 @@ namespace Microsoft.PowerToys.UITest /// The name for finding the element. /// The timeout in milliseconds. /// The found element. - public Element Find(string name, int timeoutMS = 3000) + public Element Find(string name, int timeoutMS = 5000) { return this.Find(By.Name(name), timeoutMS); } @@ -215,7 +215,7 @@ namespace Microsoft.PowerToys.UITest /// The selector to use for finding the elements. /// The timeout in milliseconds. /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) where T : Element, new() { Assert.IsNotNull(this.windowsElement, $"WindowsElement is null in method FindAll<{typeof(T).Name}> with parameters: by = {by}, timeoutMS = {timeoutMS}"); @@ -239,7 +239,7 @@ namespace Microsoft.PowerToys.UITest /// The name for finding the element. /// The timeout in milliseconds. /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) where T : Element, new() { return this.FindAll(By.Name(name), timeoutMS); @@ -252,7 +252,7 @@ namespace Microsoft.PowerToys.UITest /// The selector to use for finding the elements. /// The timeout in milliseconds. /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) { return this.FindAll(by, timeoutMS); } @@ -264,7 +264,7 @@ namespace Microsoft.PowerToys.UITest /// The name for finding the element. /// The timeout in milliseconds. /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) { return this.FindAll(By.Name(name), timeoutMS); } diff --git a/src/common/UITestAutomation/FindHelper.cs b/src/common/UITestAutomation/FindHelper.cs index 5f25dfcb15..f5a460acca 100644 --- a/src/common/UITestAutomation/FindHelper.cs +++ b/src/common/UITestAutomation/FindHelper.cs @@ -20,7 +20,7 @@ namespace Microsoft.PowerToys.UITest public static ReadOnlyCollection? FindAll(Func> findElementsFunc, WindowsDriver? driver, int timeoutMS) where T : Element, new() { - var items = findElementsFunc(); + var items = FindElementsWithRetry(findElementsFunc, timeoutMS); var res = items.Select(item => { var element = item as WindowsElement; @@ -30,6 +30,27 @@ namespace Microsoft.PowerToys.UITest return new ReadOnlyCollection(res); } + private static ReadOnlyCollection FindElementsWithRetry(Func> findElementsFunc, int timeoutMS) +{ + int retryIntervalMS = 500; + timeoutMS = 1; + int elapsedTime = 0; + + while (elapsedTime < timeoutMS) + { + var items = findElementsFunc(); + if (items.Count > 0) + { + return items; + } + + Task.Delay(retryIntervalMS).Wait(); + elapsedTime += retryIntervalMS; + } + + return new ReadOnlyCollection(new List()); + } + public static T NewElement(WindowsElement? element, WindowsDriver? driver, int timeoutMS) where T : Element, new() { @@ -37,11 +58,6 @@ namespace Microsoft.PowerToys.UITest Assert.IsNotNull(element, $"New Element {typeof(T).Name} error: element is null."); T newElement = new T(); - if (timeoutMS > 0) - { - // Only set timeout if it is positive value - driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(timeoutMS); - } newElement.SetSession(driver); newElement.SetWindowsElement(element); diff --git a/src/common/UITestAutomation/Session.cs b/src/common/UITestAutomation/Session.cs index 26bced8cb5..0ff01d3695 100644 --- a/src/common/UITestAutomation/Session.cs +++ b/src/common/UITestAutomation/Session.cs @@ -85,9 +85,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - public T Find(By by, int timeoutMS = 3000) + public T Find(By by, int timeoutMS = 5000) where T : Element, new() { Assert.IsNotNull(this.WindowsDriver, $"WindowsElement is null in method Find<{typeof(T).Name}> with parameters: by = {by}, timeoutMS = {timeoutMS}"); @@ -105,9 +105,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - public T Find(string name, int timeoutMS = 3000) + public T Find(string name, int timeoutMS = 5000) where T : Element, new() { return this.Find(By.Name(name), timeoutMS); @@ -117,9 +117,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Find(by, timeoutMS) /// /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - public Element Find(By by, int timeoutMS = 3000) + public Element Find(By by, int timeoutMS = 5000) { return this.Find(by, timeoutMS); } @@ -128,9 +128,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Find(By.Name(name), timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - public Element Find(string name, int timeoutMS = 3000) + public Element Find(string name, int timeoutMS = 5000) { return this.Find(By.Name(name), timeoutMS); } @@ -140,9 +140,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(By by, int timeoutMS = 3000) + public bool HasOne(By by, int timeoutMS = 5000) where T : Element, new() { return this.FindAll(by, timeoutMS).Count == 1; @@ -152,9 +152,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.HasOne(by, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(By by, int timeoutMS = 3000) + public bool HasOne(By by, int timeoutMS = 5000) { return this.HasOne(by, timeoutMS); } @@ -164,9 +164,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(string name, int timeoutMS = 3000) + public bool HasOne(string name, int timeoutMS = 5000) where T : Element, new() { return this.HasOne(By.Name(name), timeoutMS); @@ -176,9 +176,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.HasOne(name, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(string name, int timeoutMS = 3000) + public bool HasOne(string name, int timeoutMS = 5000) { return this.HasOne(By.Name(name), timeoutMS); } @@ -188,9 +188,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(By by, int timeoutMS = 3000) + public bool Has(By by, int timeoutMS = 5000) where T : Element, new() { return this.FindAll(by, timeoutMS).Count >= 1; @@ -200,9 +200,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Has(by, timeoutMS) /// /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(By by, int timeoutMS = 3000) + public bool Has(By by, int timeoutMS = 5000) { return this.Has(by, timeoutMS); } @@ -212,9 +212,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(string name, int timeoutMS = 3000) + public bool Has(string name, int timeoutMS = 5000) where T : Element, new() { return this.Has(By.Name(name), timeoutMS); @@ -224,9 +224,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Has(name, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(string name, int timeoutMS = 3000) + public bool Has(string name, int timeoutMS = 5000) { return this.Has(name, timeoutMS); } @@ -236,9 +236,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the elements, should be Element or its derived class. /// The selector to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) where T : Element, new() { Assert.IsNotNull(this.WindowsDriver, $"WindowsElement is null in method FindAll<{typeof(T).Name}> with parameters: by = {by}, timeoutMS = {timeoutMS}"); @@ -260,9 +260,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the elements, should be Element or its derived class. /// The name to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) where T : Element, new() { return this.FindAll(By.Name(name), timeoutMS); @@ -273,9 +273,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.FindAll(by, timeoutMS) /// /// The selector to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) { return this.FindAll(by, timeoutMS); } @@ -285,9 +285,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.FindAll(By.Name(name), timeoutMS) /// /// The name to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - public ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + public ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) { return this.FindAll(By.Name(name), timeoutMS); } @@ -416,9 +416,6 @@ namespace Microsoft.PowerToys.UITest this.windowHandlers.Add(this.MainWindowHandler); - // Set implicit timeout to make element search retry every 500 ms - this.WindowsDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(3); - if (size != WindowSize.UnSpecified) { this.SetMainWindowSize(size); diff --git a/src/common/UITestAutomation/SessionHelper.cs b/src/common/UITestAutomation/SessionHelper.cs index 3590c80fbb..2061c97001 100644 --- a/src/common/UITestAutomation/SessionHelper.cs +++ b/src/common/UITestAutomation/SessionHelper.cs @@ -41,9 +41,6 @@ namespace Microsoft.PowerToys.UITest var desktopCapabilities = new AppiumOptions(); desktopCapabilities.AddAdditionalCapability("app", "Root"); this.Root = new WindowsDriver(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), desktopCapabilities); - - // Set default timeout to 5 seconds - this.Root.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); } /// @@ -59,9 +56,6 @@ namespace Microsoft.PowerToys.UITest Assert.IsNotNull(this.Driver, $"Failed to initialize the test environment. Driver is null."); - // Set default timeout to 5 seconds - this.Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); - return this; } diff --git a/src/common/UITestAutomation/UITestBase.cs b/src/common/UITestAutomation/UITestBase.cs index 494f622be5..288fd42ce1 100644 --- a/src/common/UITestAutomation/UITestBase.cs +++ b/src/common/UITestAutomation/UITestBase.cs @@ -69,9 +69,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - protected T Find(By by, int timeoutMS = 3000) + protected T Find(By by, int timeoutMS = 5000) where T : Element, new() { return this.Session.Find(by, timeoutMS); @@ -82,9 +82,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - protected T Find(string name, int timeoutMS = 3000) + protected T Find(string name, int timeoutMS = 5000) where T : Element, new() { return this.Session.Find(By.Name(name), timeoutMS); @@ -94,9 +94,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.Find(by, timeoutMS) /// /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - protected Element Find(By by, int timeoutMS = 3000) + protected Element Find(By by, int timeoutMS = 5000) { return this.Session.Find(by, timeoutMS); } @@ -105,9 +105,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.Find(name, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// The found element. - protected Element Find(string name, int timeoutMS = 3000) + protected Element Find(string name, int timeoutMS = 5000) { return this.Session.Find(name, timeoutMS); } @@ -117,9 +117,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(By by, int timeoutMS = 3000) + public bool HasOne(By by, int timeoutMS = 5000) where T : Element, new() { return this.FindAll(by, timeoutMS).Count == 1; @@ -129,9 +129,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.HasOne(by, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(By by, int timeoutMS = 3000) + public bool HasOne(By by, int timeoutMS = 5000) { return this.Session.HasOne(by, timeoutMS); } @@ -141,9 +141,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(string name, int timeoutMS = 3000) + public bool HasOne(string name, int timeoutMS = 5000) where T : Element, new() { return this.Session.HasOne(By.Name(name), timeoutMS); @@ -153,9 +153,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.HasOne(name, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if only has one element, otherwise false. - public bool HasOne(string name, int timeoutMS = 3000) + public bool HasOne(string name, int timeoutMS = 5000) { return this.Session.HasOne(name, timeoutMS); } @@ -165,9 +165,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(By by, int timeoutMS = 3000) + public bool Has(By by, int timeoutMS = 5000) where T : Element, new() { return this.Session.FindAll(by, timeoutMS).Count >= 1; @@ -177,9 +177,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.Has(by, timeoutMS) /// /// The selector to find the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(By by, int timeoutMS = 3000) + public bool Has(By by, int timeoutMS = 5000) { return this.Session.Has(by, timeoutMS); } @@ -189,9 +189,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the element, should be Element or its derived class. /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(string name, int timeoutMS = 3000) + public bool Has(string name, int timeoutMS = 5000) where T : Element, new() { return this.Session.Has(By.Name(name), timeoutMS); @@ -201,9 +201,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.Has(name, timeoutMS) /// /// The name of the element. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// True if has one or more element, otherwise false. - public bool Has(string name, int timeoutMS = 3000) + public bool Has(string name, int timeoutMS = 5000) { return this.Session.Has(name, timeoutMS); } @@ -214,9 +214,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the elements, should be Element or its derived class. /// The selector to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - protected ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + protected ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) where T : Element, new() { return this.Session.FindAll(by, timeoutMS); @@ -228,9 +228,9 @@ namespace Microsoft.PowerToys.UITest /// /// The class of the elements, should be Element or its derived class. /// The name of the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - protected ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + protected ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) where T : Element, new() { return this.Session.FindAll(By.Name(name), timeoutMS); @@ -241,9 +241,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.FindAll(by, timeoutMS) /// /// The selector to find the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - protected ReadOnlyCollection FindAll(By by, int timeoutMS = 3000) + protected ReadOnlyCollection FindAll(By by, int timeoutMS = 5000) { return this.Session.FindAll(by, timeoutMS); } @@ -253,9 +253,9 @@ namespace Microsoft.PowerToys.UITest /// Shortcut for this.Session.FindAll(By.Name(name), timeoutMS) /// /// The name of the elements. - /// The timeout in milliseconds (default is 3000). + /// The timeout in milliseconds (default is 5000). /// A read-only collection of the found elements. - protected ReadOnlyCollection FindAll(string name, int timeoutMS = 3000) + protected ReadOnlyCollection FindAll(string name, int timeoutMS = 5000) { return this.Session.FindAll(By.Name(name), timeoutMS); } diff --git a/src/modules/Hosts/Hosts.UITests/HostModuleTests.cs b/src/modules/Hosts/Hosts.UITests/HostModuleTests.cs index fbdc92fbe7..681529c7ef 100644 --- a/src/modules/Hosts/Hosts.UITests/HostModuleTests.cs +++ b/src/modules/Hosts/Hosts.UITests/HostModuleTests.cs @@ -40,7 +40,7 @@ namespace Hosts.UITests this.RemoveAllEntries(); // 'Add an entry' button (only show-up when list is empty) should be visible - Assert.IsTrue(this.HasOne("Add an entry1"), "'Add an entry' button should be visible in the empty view"); + Assert.IsTrue(this.HasOne("Add an entry"), "'Add an entry' button should be visible in the empty view"); // VisualAssert.AreEqual(this.Find("Entries"), "EmptyView"); @@ -297,10 +297,7 @@ namespace Hosts.UITests foreach (var deleteBtn in this.FindAll