I need to find UI Elements within my Windows Desktop WPF application using xpath and Appiums xpath-selector.
It's working fine for "simple" applications but fails for my target application.
My environment is:
OS: Windows 10
Target Application: x86 WPF
Appium Windows Driver: 4.0.0.6 beta
Appium Desktop Application: 1.13.0
Selenium WebDriver: 3.141.0
This is what I am trying:
Once I have fired up my target application by the Appium desktop application, its session window tells me the xpath to UI-elements, such as (also see the screenshots):
xpath:
"/Windows/ToolBar/Tab/TabItem[1]"
Appium Session Window Screenshot:
Microsofts inspect.exe screenshot:
The wired thing now is:
If I am using the xpath-string that appium shows me, in order to find the corresponding UI-Element within this session manager itself (by using the search-feature and selecting the xpath-selector), it's unable to find any elements (see screenshots):
Also, if I am using a trivial xpath-string such as
"//*"
or
"/Window"
it fails as well by not finding any elements.
Here, as a contrast, are the same steps captured by screenshots for the baretail.exe notepad application, for which it works, i.e. where I am able to use the provided xpath-string to correctly find the corresponding UI-Element.
Appium Session Windows:
Microsofts inspect.exe:
Appium Session Window search for UI-Element - query:
Appium Session Window search for UI-Element - result:
Eventually, I need to use this from within a C#-project, for which I am using the following code, but i am getting the same result, which is, not finding any UI-Elements matching my xpath-string.
(I debugged the Appium source so far that I already know that the FindElement-request using the xpath-selecotr is submitted successfully, but the Appium server responds with an empty result set of found UI-Elements.)
AppiumOptions options = new AppiumOptions();
options.AddAdditionalCapability("app", "path/to/my/target/application");
options.AddAdditionalCapability("deviceName", "WindowsPC");
options.AddAdditionalCapability("platformName", "Windows");
options.AddAdditionalCapability("newCommandTimeout", "60000");
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), options);
Assert.IsNotNull(session);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5);
string xpath = "/Window/MenuBar/MenuItem[2]"; // valid xpath to an UI-Element
var result = session.FindElementsByXPath(xpath); // successfully returns an empty collection
Anyone, any ideas? Please ...
Related
Recently, I have upgraded my Selenium version from 2.53 to 4.1.2 to enable testing of our application on MS EDGE IE11. But we are intermittently facing issues while retrieving number of windows open in MS EDGE IE11 with selenium-4.1.2
Did anyone else facing similar kind of issues with Selenium-4.1.2 ?
Below is piece of code I have tried on MS EDGE IE11. Sometimes we could see its returning correct no. of windows but sometime not. We are also using sufficient wait-time before retrieving number of windows.
Note - This is working absolutely fine on IE11 browser with Selenium-4.1.2
int noOfWindowsOpen = driver.getWindowHandles().size();
Expectation : It should always return correct value of no. of windows open.
Once you open the new tab / window before you count the number of WindowHandles you need to induce WebDriverWait for numberOfWindowsToBe() as follows:
driver.get("http://www.google.com");
((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
new WebDriverWait(driver, 10).until(ExpectedConditions.numberOfWindowsToBe(2));
int noOfWindowsOpen = driver.getWindowHandles().size();
It seems to be a known limitation in automating Edge IE mode. It says:
To ensure the new window has been created successfully and IEDriver
has detected it, you must continuously check the result of the Get
Window Handles command until it contains a handle to the new window.
You can try the sample code in it:
int initialHandleCount = driver.getWindowHandles().size();
driver.findElement(By.id("<Id of the button that will open a new window>")).click();
Set<string> newHandles = driver.getWindowHandles();
while (newHandles.size() == initialHandleCount) {
newHandles = driver.getWindowHandles();
}
I have found a work-around for above problem.
Before executing, make sure all the instances of ME Edge, IE and IE Driver are closed. If not, kill them forcefully from task manager and then re-run the Test Script. Script will identify the new window properly.
Thanks
I'm running a set of automated UI tests using Appium/Winappdriver on Windows 10. The test framework is compiled in Visual Studio 2017 using mstest.
The problem that I am having is with tests that use a right-click to open a context menu, then select an element from the resulting menu. Locally, it works. It also works on our remote CI/CD machine. However, it does not work for the other two developers on the project, and we've spent two business days fruitlessly trying to figure out why.
We have the same Windows version (Windows 10, version 1903), we have the same Visual Studio 2017 (we also tried it with 2019, no luck), we have the same monitor resolution (1920 x 1080), we are targeting the same .NET framework (4.72), we have the same WinAppDriver, etc.
Everything else works just fine. But when the UI Test reaches that context menu, the test fails with the error "An element could not be located on the page using the given search parameters."
I used the WinAppDriver UI Recorder to find the XPath for the element. We also used it on the other user's machine and confirmed that, as far as the UI Recorder is concerned, the path is identical on both machines.
The specific call that fails:
Session.FindElementByXPath("/Pane[#ClassName=\"#32769\"][#Name=\"Desktop 1\"]/Menu[#ClassName=\"#32768\"][#Name=\"Context\"]/MenuItem[#Name=\"" + itemName + "\"]");
The WinAppDriver call on my machine (success):
{"using":"xpath","value":"/Pane[#ClassName=\"#32769\"][#Name=\"Desktop 1\"]/Menu[#ClassName=\"#32768\"][#Name=\"Context\"]/MenuItem[#Name=\"New Location\"]"}
HTTP/1.1 200 OK
Content-Length: 125
Content-Type: application/json
{"sessionId":"8970FDC1-E869-4304-A87D-D8F2CB711EA2","status":0,"value":{"ELEMENT":"42.856234.4.-2147483646.8140.18614751.1"}}
and the same call on the other user's machine (fail):
{"using":"xpath","value":"/Pane[#ClassName=\"#32769\"][#Name=\"Desktop 1\"]/Menu[#ClassName=\"#32768\"][#Name=\"Context\"]/MenuItem[#Name=\"New Location\"]"}
HTTP/1.1 404 Not Found
Content-Length: 139
Content-Type: application/json
{"status":7,"value":{"error":"no such element","message":"An element could not be located on the page using the given search parameters."}}
Again, everything else works. Other UI tests that don't use the right-click context menus work just fine. It's only this particular area that fails.
What I've tried so far:
Using Thread.Sleep to force a long wait before making the call
Wrapping the call with a DefaultWait and polling it over a period of several seconds to see if the element becomes available during that time.
When the "An element could not be located" is thrown, retry up to a set number of times to find the element.
Lots and lots of double-checking to make sure we're both on the same version of the code, same libraries, same nuget packages, etc.
Trying a much broader locator ( Session.FindElementByName(itemName); )
The biggest head-scratcher is that when we check with UI Recorder, the element is there. When we check on my machine or the remote build machine, WinAppDriver can find it normally. But for some reason WinAppDriver can't find it on my coworker's machines.
This is a peculiar issue indeed.
I'd like to rule out the XPath selector as a potential problem here. Based on your syntax, it looks like you are using an absolute XPath. These can be extremely brittle depending on the circumstances. Not saying it's the root problem, but I would like to try a different selector to rule this out.
{"using":"xpath","value":"//MenuItem[#Name=\"New Location\"]"}
Using relative // notation tells your path to look anywhere on the page, rather than following a specific path down to the element itself.
Give this a try, and let me know if it helps at all.
For my application context menu is listed out of the DOM of actual application in inspect.exe. So switching back to desktop session after selecting the context menu worked fine for me.
var regressionChannelRow = labelProcessorSession.FindElementByName("5000");
Actions action1 = new Actions(labelProcessorSession);
regressionChannelRow.Click();
action1.ContextClick(regressionChannelRow).Perform();
Now creating a desktop session to get the "Stop" option from the context menu
AppiumOptions appCapabilities = new AppiumOptions();
appCapabilities.AddAdditionalCapability("app", "Root");
WindowsDriver<WindowsElement> desktopSession;
desktopSession = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appCapabilities);
below is the context menu option which I need to select, remember to use desktop session here
var stopService = desktopSession.FindElementByName("Stop");
stopService.Click();
I've just replicated this issue. I was working on a test that I wrote last week, which was now getting stuck trying to find the context menu from a desktop session. I tried using various XPaths, searching by class name or just name, but it didn't seem to make any difference.
Eventually I tried closing Spotify, and that solved the issue! If you're experiencing this problem then try closing every application window possible.
I'm launched Selenium Grid (Node and Hub),and testing Web app. But I need provide some action on Windows Open dialog. Can I do that with and how using AutoIt on next way : capabilities.setCapability("browser", "AutoIt") ?
Refer this link for step by step guide on how to use AutoIT with Selenium. This involves using the tool to create a .au3 script which you will need to execute from your code. But from your question, if you want something like capabilities.setCapability("browser", "AutoIt"), you have to use AutoItDriverServer (See README for installation steps).
Its a Selenium like Interface wrapper for AutoIt, so you can basically operate your windows application by the very same selenium methods you are familiar with.
How to Use it:
In the 'autoitdriverserver_python' directory, run the "server.py" file. Now, whenever you want to perform actions on your windows application, just create a new remote driver with capability of 'browserName':'AutoIt'. Ex-
driver = webdriver.Remote( command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities={'browserName':'AutoIt'})
driver.get("path to your application")
driver.switch_to_window("window name")
driver.find_element_by_id("your id").click()
Note as mentioned in docs:
AutoIt doesn't find or handle multiple elements specified by location
strategy, therefore, finding elements in WebDriver is not implemented
for AutoItDriverServer. You can only find singular elements.
See this link for all the available commands. To locate elements, for example through ID, you need AutoIT info tool which is available in the entire package.
I am working on writing a story for a bdd framework which uses jbehave/selenium/webdriver and am having a problem where the test encounters an error while running the story but appears to be fine when running manually. I'm having a problem where javascript for the functionality I'm testing behaves slightly different when I'm running tests manually on firefox vs through selenium web driver on the same system/version of firefox and this difference is causing a js error.
I've debugged and basically the root of the problem appears to be that var request_XML_container = $('div_appendpoint_id'); returns something different when I'm running the test manually vs when I run through the bdd framework.
var request_XML_container = $('div_appendpoint_id');
request_XML_container.innerHTML = encoded_xml_from_request;
var pos = method_to_get_position('id_of_place_div_should_be_appended_to');
// JS exception is thrown saying that style is not defined **ONLY**
// when running through web driver. Running test manually on
// same system and same browser works fine.
request_XML_container.style.left = (pos[0] - 300) + 'px';
request_XML_container.style.top = (pos[1] + 25) + 'px';
request_XML_container.style.display = "block";
Why this would work fine when running manually that var request_XML_container = $('div_appendpoint_id'); would return an item with style defined, but when running through webdriver that the style attribute of the element would not be defined?
UPDATE: I had originally thought that this was updating an iframe, but I read the markup wrong and the iframe I saw is a sibling - not a parent - of the element where the response is being appended to. I'm trying to simply append the response to a div. To be honest, this only makes things more confusing as grabbing a div by id should be pretty straight forward and I'm now sure why webdriver would be producing a different return element in this situation.
UPDATE 2: Steps to reproduce and information about the system I'm on:
Use webdriver to navigate to this url: http://fiddle.jshell.net/C3VB5/11/show/
Have webdriver click the button. It should not work
Run your test again, but pause put a breakpoint at your code to click the driver
Click the button on the browser that webdriver opened. It should not work
Refresh the browser page on the browser that webdriver opened. Now, it should work.
System details:
OS : OS X 10.8.5 (12F37)
IDE : Eclipse Kepler: Build id: 20130614-0229
Browser (used manually and by webdriver) : Firefox 23.0.1
Selenium version: 2.35.0
UPDATE 3: I have provided this maven project on github to aid in reproducing: https://github.com/dkwestbr/WebdriverBug/tree/master/Webdriver
Synopsis/tl:dr; Basically, in certain situations it appears as though webdriver is overwriting the '$()' javascript method with a method that does not return an HTMLElement with innerHTML or style defined (among other things). This post details the issue and how to reproduce.
I have opened this ticket to track the issue: https://code.google.com/p/selenium/issues/detail?id=6287&thanks=6287&ts=1379519170
I have confirmed that this is a bug with the Thucydides framework (understandable since they still aren't at a 1.0 release).
Issue can be tracked here: https://java.net/jira/browse/THUCYDIDES-203
Hi I am trying to run my selenium webdriver on IE9.
WebDriver version : 2.32.0
IE:9
IEDriverServer_win32:2.32.3
windows7
Below is my code:
File IEDriver=new File(System.getProperty("user.dir")+File.separator+"BrowserDrivers"+File.separator+"IEDriverServer.exe");
System.setProperty("webdriver.ie.driver", IEDriver.getAbsolutePath());
DesiredCapabilities cap=DesiredCapabilities.internetExplorer();
cap.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver=new InternetExplorerDriver(cap);
driver.get("http://in00616:8421/GS");
Thread.sleep(3000);
//driver.findElement(By.id("j_username")).sendKeys("admin");
//driver.findElement(By.id("j_password")).sendKeys("admin");
driver.findElement(By.xpath(".//input[#id='j_username']")).sendKeys("admin");
driver.findElement(By.xpath(".//input[#id='j_password']")).sendKeys("admin");
driver.findElement(By.id("login")).submit();
Thread.sleep(2000);
driver.findElement(By.xpath(".//button[text()='Securities']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath(".//span[text()='Issue']")).click();
Thread.sleep(2000);
driver.findElement(By.id("tabSecurities_Issue_Request_for_Issues")).click();
Above code logs in to my site but then when I try to click on Securities button I am not able to do it. Securities button starts flickering and then I am notified that unable to find the element.
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
Unable to find element with xpath == .//span[text()='Issue Type']
(WARNING: The server did not provide any stacktrace information) –
Same code works fine in FireFox.
Please help as i am suppose to test my UI on InternetExplorer.
I think it is the version compatibility issue.
Can anyone suggest the compatible version set for IEDriverServer, Selenium WebDriver and IE which is in working condition.
As this SO answer points out, IE does not have native XPath support. Instead, Selenium WebDriver uses an old third party xpath library when IE is being used. Firefox has integrated support for XPath, which is why your selectors work fine in that browser.
I would highly recommend you update your selectors to instead use CSS selectors. They are supported across all browser, are easier to read, understand, and pick up, and they are pretty fast.
You can learn more about how to use CSS selectors from some different tuturials here, here, and here, and a CSS selectors cheatsheet.
Also, whenever possible, please try to not select an element by the text it contains. If you can select an element by its ID, class, other attribute, or even through the DOM chain (i.e. "div.1 > div.2 > span.a > a.b"), is better than trying to select an element by text.
Webdriver has difficulty with IE using locators. It seems like Murnal has difficulty using CSS locator. My advice would be you HAVE to use other locators if one doesnt work. This issue comes again and again while using non firefox browser. In the meantime an easier way to come up with alternate locator is use Firefox selenium IDE, there in the boxes where you type command you will see it gives alternate locator as well. Copy that and try plugging tha in your webdriver's findelement script.
Hi all i have found out that it was the issue of Selenium Webdriver 2.32 with IEDriver_Server2_32. After trying out permutation & Combination with latest available webdriver versions and IEDriver_Server, i have found out suitable stable configuration to work on IE9 below is the stable configuration : Webdriver : 2.33.0 IEDriver_Server : 2.33.0. There is still small issue but i am trying to look for workaround. Issue : In IE if some control's tooltip overlaps other control than IE is not able to find out that control. i guess this issue is with IEs working. IE uses nativeEvents to perform operation hence it is not able to locate that control. In FF it is able to find out that control and it is working fine. Thanks everyone.