这两天一直在研究uwp元素定位,新版本的WinAppDriver新增了XPath元素定位方法。
在UWP中FindElementByXPath定位方法路径的编写方法目前还在学习中,它对节点的大小写区分,所以在使用XPath定位过程中,还没有成功实现元素的定位,
如我要查找页面上一个叫"Hardware scan"的Button,那可以这样写:
driver.FindElementByXPath("//Button[@name='Hardware scan']").Click();//it does not work
在使用页面元素检测工具inspect.exe时,元素的所有className都是小写显示,所以在用XPath定位元素时经常会报invalid XPath ...
在gitHub上发帖请教时,有人回复说是winAppDriver大小写敏感,需要严格区分大小写,建议把页面的Page Source导出来看。于是又网上查找appium打印page source的方法:System.IO.File.AppendAllText("D:\\pagesource.xml",driver.PageSource);
通过不断学习研究,发现WinAppDriver中的xpath需要将节点和属性的首字母大写,属性值需要用双引号进行引用:
driver.findElementByXPath("//Button[@Name=\"Hardware scan\"]");//it works
目前使用元素相对节点路径方法能够成功,但使用绝对路径还未成功,目前也在疑惑元素的绝对路径,是按照page source里面的路径还是按照检测工具inspect.exe中显示的路径。但按目前
测试的结果来说,按照inspect.exe工具显示的结构树的路径,写为元素的XPath定位路径是没有跑成功。
注意:这里通过节点的index值来区分时需要注意,index值是从0开始,不是从1开始。
二.定位元素时多元素重名定位的处理
1.自己写的元素显示等待的方法:
public static
Windows Element waitForElement(RemoteWebDriver driver, String name,int timeOut)
{
//等待元素
RemoteWebElement ele = null;
try
{
//等待页面加载30s
//driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(30));
//driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut));
//通过元素的name进行查找,一直等待,直到时间截至
ele = (RemoteWebElement)wait.Until(ExpectedConditions.ElementExists(By.Name(name)));
if (ele != null)
return ele;
else
return null;
}
catch (Exception e)
{
Log.writeLog("元素查找","查找name为" + name + "的元素异常,异常原因:" + e.Message.ToString());
}
return ele;
}
2.通过getAttribute来判断元素
测试页面元素最好另外写个方法,以判断元素的属性,如:
Thread.Sleep(TimeSpan.FromSeconds(10));
foreach (WindowsElement e in session1.FindElementsByName("Check for updates"))
{
if (e.GetAttribute("ClassName").Equals("Button"))
{
Console.WriteLine(e.GetAttribute("frameworkid"));
Console.WriteLine(e.GetAttribute("LegacyIAccessible.DefaultAction"));
Console.WriteLine(e.GetAttribute("isenabled"));
// 不支持ancestors属性
Console.WriteLine(e.GetAttribute("ancestors"));
Console.WriteLine(e.GetAttribute("runtimeid"));
Console.WriteLine(e.GetAttribute("localizedcontroltype"));
Console.WriteLine(e.GetAttribute("AutomationId"));
//Console.WriteLine(e.Location);
Console.WriteLine();
}
}
Console.ReadKey();
可以通过getAttribute获取元素的相关属性,但是getAttribute使用不是很方便,然后就另外写了个通过元素的Name查找元素,来打印元素的一些常见属性,判断界面上有多少同名元素
3.通过name简化打印页面元素的属性
public static void findElementToList(RemoteWebDriver driver, string Name)
{
//隐式等待,等待页面加载
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(60));
foreach (RemoteWebElement ele in driver.FindElementsByName(Name))
{
Console.WriteLine("Text:"+ele.Text+"\t TagName:"+ele.TagName+"\t Location:"+ele.Location+"\t Enabled:"+ele.Enabled+"\t Displayed"+ele.Displayed);
}
}
三.处理同名元素的方式
在实现Appium做UWP功能
自动化测试过程中,经常遇到界面加载太慢导致元素找不到的问题,所以在写代码过程中最好使用显示等待,减少因为页面加载的原因导致报错;另外测试的重难点是元素的定位和当多个元素重名时的处理方式,
目前我们在处理同名元素的方式主要是两种:
1.通过Name查找元素,然后通过index值操作元素
在使用inspect.exe元素检测工具检测时,发现inspect工具并不是那么好用,所以一般都是通过自己写的findElementToList方法来判断当前页面上重名的元素位置,再结合inspect工具判断不同位置的元素对应界面那个位置,然后要对对应元素操作时就用FindElementsByName("元素名")[index]方式操作,这里需要注意的是index值是从0开始的,不像selenium中定位时index是从1开始
2.通过getAttribute方法实现
首先findElementsByName("元素名")获取到所有元素,再通过getAttribute属性来获取要的属性值,判断是否是预期的属性值,从而进行对应操作,如:
foreach(WindowElement e in driver.FindElementsByName("元素名"))
{
//判断ClassName是否是按钮
if(e.GetAttribute("ClassName").Equals("Button"))
e.click();//点击操作
e.SendKeys("*****");//输入字符。。。
}
3.结合WinAPPDriver支持的几种元素定位,再结合方法1和方法2进行操作