gpt4 book ai didi

c# - 为什么我的 ReactiveUserControl 或 ReactUI 应用程序无法使用 Selenium 自动测试和 WinAppDriver(C# 测试解决方案)

转载 作者:行者123 更新时间:2023-12-05 04:33:28 25 4
gpt4 key购买 nike

我有使用 C#、WinAppDriver(又名 WAD)和 Selenium 开发大型自动化测试解决方案的经验。这将测试大型 WPF Windows 应用程序。

到目前为止,还不错。

现在您可以想象被测系统已经达到版本 2,它与此类似,但现在基本的 WPF/XAML 使用 ReactiveUserControl 或 React UI。

使用我之前有效的测试解决方案,我为版本 2/React 应用程序创建了一个非常简单的测试项目,到目前为止,应用程序已启动并且“驱动程序” session 处于事件状态,但使用了许多“FindElementsBy”selenium 方法我找不到任何东西。

我通过让我的测试启动 Notepad++ 而不是我的 React UI 系统来检查这一点,因为被测系统和我的测试完美运行。我还测试了记事本、Windows 照片查看器、Windows 资源管理器,当然还有我公司内部开发的 WPF 应用程序。这些都有效,但 React 应用程序元素似乎无法自动测试。

有关信息,这是来自 React UI 应用程序的一些 xaml:

<rxui:ReactiveUserControl x:Class="MyReactUIApp.Views.MyView"
x:TypeArguments="vms:MyViewModel"
xmlns:rxui="http://reactiveui.net"
xmlns:vms="clr-namespace:MyReactUIApp.ViewModels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="640" Background="{StaticResource White}">

现在我不是 xaml 专家,但我认为这里的线索是 ReactiveUserControl。我不是 100% 确定它与代码中的“驱动程序”变量一起工作:

protected static WindowsDriver<RemoteWebElement> driver;

无论如何,这是我的代码。您可以看到我有一个名为“MyShortTest()”的测试,并且在该测试运行之前,有一个 [TestInitialize] 调用方法 Setup(context)。您可以看到 Setup 方法启动应用程序,然后找到该进程的 MainWindowHandle,然后将具有该主窗口句柄的进程分配给驱动程序变量。

一切正常,没有错误。

但是在 MyShortTest 中,FindElementsByAccessibilityId 方法找不到任何东西。他们应该找到 ID 为“Email”的元素,因为它就在那里。它还应该找到名为“TitleBar”的元素,它适用于 Notepad++ 等,但不适用于我正在测试的 React 系统。

测试代码和类:

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace notepad_AutoTest
{
[TestClass]
public class BasicSanityCheckTests : driver_class
{

[TestMethod]
public void MyShortTest()
{
//Check if worked
bool foundSomething = false;
try
{
//Notepad++ has an element with the ID "TitleBar", find it...

//WHY IS THE titleBarCount = 0 ???????????????
int titleBarCount_AS1 = driver.FindElementsByAccessibilityId("TitleBar").Count; //Notepad OK //Notepad++ OK //Windows Photo Viewer OK
if (titleBarCount_AS1 > 0)
{
foundSomething = true;
}
}
catch { }

try
{
//MyReactUIApp has an element with the ID "Email", find it...
//WHY IS THE emailCount_AS1 = 0 ???????????????
int emailCount_AS1 = driver.FindElementsByAccessibilityId("Email").Count;
if (emailCount_AS1 > 0)
{
//Why is this not found???????
foundSomething = true;
}
}
catch { }

//Why is foundSomething still false????????

Assert.IsTrue(foundSomething, "We did not find anything in the application under test.");

//Close
driver.CloseApp();
}

#region Class Initialize and Cleanup
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
if (!CommonMethods.IsProcessOpen(GUI_Map.AppUnderTest_ProcessName, false))
{
//Launch etc
Setup(context);
}
}

[ClassCleanup]
public static void ClassCleanup()
{
TearDown();
}
#endregion Class Initialize and Cleanup
}
}

驱动程序/ session 代码和类:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Remote;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace notepad_AutoTest
{
public class driver_class
{
//WinAppDriver url
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";

//driver
protected static WindowsDriver<RemoteWebElement> driver;
//protected static OpenQA.Selenium.Appium.Service.AppiumLocalService service;

//Launch notepad++ - variables
//public static string filePath = "C:\\Program Files (x86)\\Notepad++\\";
//public static string fileName = "notepad++.exe";
//public static string processName = "Notepad++";

//Launch MyReactUIApp - variables
public static string filePath = "C:\\Projects\\MyReactiveUI_App\\";
public static string fileName = "myReactUIApp.exe";
public static string processName = "MyReactUIApp";

public static string filepathWinAppD = "C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe";

public static void Setup(TestContext context)
{
// Launch Windows Application Driver if it is not already launched
if (driver == null)
{
TearDown();

//Check if Windows Application Driver is running and launch it if needed.
if (!CommonMethods.IsProcessOpen("WinAppDriver", false))
{
//Launch Windows Application Driver
Process winAppD = new Process();
winAppD.StartInfo.FileName = filepathWinAppD;
winAppD.Start();

while (!CommonMethods.IsProcessOpen("WinAppDriver", true))
{
Thread.Sleep(500);
}
}

// Launch the application and session
//Options - filepath to launch
AppiumOptions options = new AppiumOptions();
options.AddAdditionalCapability("app", filePath);

//Check the exe file exists
Assert.IsTrue(File.Exists(filePath + fileName),
"Application does not exist in the location: " + filePath.ToString(), filePath);

try
{
//LaunchWPF app and wpf session
if (!CommonMethods.IsProcessOpen(processName, false))
{
//Launch application under test
ProcessStartInfo psi = new ProcessStartInfo();
psi.WorkingDirectory = filePath;
psi.FileName = fileName;
Process.Start(psi);

DateTime startLaunch = DateTime.Now;
int i = 0;
while (!CommonMethods.IsProcessOpen(processName, true) && !CommonMethods.TimedOut(startLaunch, 30))
{
Thread.Sleep(500 + i);
i += 100;
}
}

string TopLevelWindowHandleHex = null;
IntPtr TopLevelWindowHandle = new IntPtr();
DateTime startFindWindow = DateTime.Now;

startFindWindow = DateTime.Now;
int processFindCount = 0;

while (TopLevelWindowHandleHex == null)
{
if (CommonMethods.TimedOut(startFindWindow, 30))
{
Assert.Fail("Failed to find Process for application under test " + processName + " attempts: " + processFindCount);
}

foreach (Process SUT_Process in Process.GetProcesses())
{
if (SUT_Process.ProcessName.ToUpper().StartsWith(processName.ToUpper()))
{
TopLevelWindowHandle = SUT_Process.MainWindowHandle;
TopLevelWindowHandleHex = SUT_Process.MainWindowHandle.ToString("x");
}
}
}

AppiumOptions appOptions = new AppiumOptions();
appOptions.AddAdditionalCapability("appTopLevelWindow", TopLevelWindowHandleHex);
appOptions.AddAdditionalCapability("ms:experimental-webdriver", true);
appOptions.AddAdditionalCapability("ms:waitForAppLaunch", "25");
driver = new WindowsDriver<RemoteWebElement>(new Uri("http://127.0.0.1:4723"), appOptions);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);
}
catch (Exception ex)
{
Assert.Fail("Failed to launch " + processName);
}
finally
{
//Assert it's running
Assert.IsNotNull(driver);
Assert.IsNotNull(driver.SessionId);
}
}
}

public static void TearDown()
{
// Close the application and delete the session
if (driver != null)
{
driver.Quit();
driver = null;
}
}
}

最佳答案

尝试将 AutomationProperties.AutomationId 添加到 rxui:ReactiveUserControl 元素。

这应该使元素对 Windows 应用程序驱动程序可见。

source

更新:这就是我们如何让自定义图表对 win 应用程序驱动程序可见 -

public abstract class Chart : Control 
{
protected Canvas Canvas { get; private set; }
private ItemsControl _legend;

protected override AutomationPeer OnCreateAutomationPeer()
{
return new ChartAutomationPeer(this);
}

private sealed class ChartAutomationPeer : FrameworkElementAutomationPeer
{
private readonly Chart _owner;
private readonly string _controlName;

/// <summary>
/// Initializes a new instance of the <see cref="ChartAutomationPeer"/> class.
/// </summary>
/// <param name="owner">Owner class.</param>
public ChartAutomationPeer(Chart owner)
: base(owner)
{
_owner = owner;
_controlName = _owner?.GetType().Name;
}

/// <inheritdoc />
protected override string GetClassNameCore()
{
return _controlName;
}

/// <inheritdoc />
protected override List<AutomationPeer> GetChildrenCore()
{
Canvas canvas = _owner.Canvas;
ItemsControl legend = _owner._legend;

var list = new List<AutomationPeer>();
if (canvas != null)
{
list.Add(new FrameworkElementAutomationPeer(canvas));
}

if (legend != null)
{
list.Add(new FrameworkElementAutomationPeer(legend));
}

return list;
}
}
}


关于c# - 为什么我的 ReactiveUserControl 或 ReactUI 应用程序无法使用 Selenium 自动测试和 WinAppDriver(C# 测试解决方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71409059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com