我想使用微软的UI Automation做自动化测试,目标程序是使用c++调用cef加载的html网页。我本人使用的是c++语言。下面的代码是枚举目标网页中的元素:
int CHtml5Automation::Init(HWND hWndBrowser)
{
m_hBrowserWnd = hWndBrowser;
int nRet = 0;
HRESULT hr = S_OK;
do
{
if (!IsWindow(m_hBrowserWnd))
{
nRet = UIAE_INVALID_HWND;
break;
}
hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation,
reinterpret_cast<void**>(&m_pClientUIA));
if (FAILED(hr))
{
nRet = UIAE_IUIAutomation;
break;
}
hr = m_pClientUIA->ElementFromHandle(m_hBrowserWnd, &m_pRootElement);
if (FAILED(hr))
{
nRet = UIAE_GET_ROOT_ELEMENT;
break;
}
} while (false);
return nRet;
}
int CHtml5Automation::BuildTrueTree()
{
HRESULT hr = S_OK;
int nRet = 0;
do
{
// 此条件,可以遍历到窗口、文档、按钮、图像、文本等元素,
// 但无法遍历到“组”这种元素,即使组元素有AutomationId.
// 通过AutomationId条件,也拿不到组元素。
IUIAutomationCondition* pCondition = nullptr;
hr = m_pClientUIA->CreateTrueCondition(&pCondition);
if (FAILED(hr))
{
nRet = -2;
break;
}
CComPtr<IUIAutomationElementArray> pElementFound;
hr = m_pRootElement->FindAll(TreeScope_Subtree, pCondition, &pElementFound);
if (FAILED(hr) || nullptr == pElementFound)
{
nRet = UIAE_FIND_CONTROL;
break;
}
int nEleCount = 0;
pElementFound->get_Length(&nEleCount);
for (int i = 0; i < nEleCount; i++)
{
IUIAutomationElement* pElement = nullptr;
hr = pElementFound->GetElement(i, &pElement);
if (FAILED(hr))
{
nRet = UIAE_GET_CONTROL;
break;
}
}
} while (false);
return 0;
}
上面的代码,可以遍历到html中的button、image等元素,但无法遍历到div元素。可是我使用c#代码:
IntPtr hSharehubWnd = new IntPtr(value: 0x00090C30);
AutomationElement shareHub = AutomationElement.FromHandle(hSharehubWnd);
AutomationElementCollection c = shareHub.FindAll(TreeScope.Subtree, Condition.TrueCondition);
if (c.Count > 0)
{
foreach (AutomationElement element in c)
{
int n3 = 0;
}
}
就可以遍历到所有元素。
有人可以指点一下吗?按理说,它们用的都是True这个条件来遍历的。