Can I use WhiteUI and FlaUI together in a project?
public TestStack.White.Application app = null;
public TestStack.White.UIItems.WindowItems.Window=null;
var processStartInfo = new ProcessStartInfo(#"winword.exe");
var application = Application.Launch(processStartInfo);
app=Application.Attach("winword");
FlaUI.Core.Application fpp = (FlaUI.Core.Application)app;
TestStack.White.UIItems.WindowItems.Window window = app.GetWindow("Microsoft Word");
FlaUI.Core.AutomationElements.Window fwin = (FlaUI.Core.AutomationElements.Window) Window;
Unable to cast window and application of Test Stack to FlaUI.
You would need to get the underlying AutomationElement from the White control and then create the FlaUI control using that AutomationElement. This means you will be limited to using UIAv2 only since White does not have a UIAv3 implementation.
Every UIItem in White exposed a AutomationElement property where you can get the underlying UIAv2 wrapper. Then you should be able to construct the FlaUI UIA2FrameworkAutomationElement using the AutomationElement from White as the second parameter. Then you will pass the UIA2FrameworkAutomationElementfrom FlaUI into the ComboBox from FlaUI. So it will look something like the following.
var processStartInfo = new ProcessStartInfo(#"winword.exe");
var application = Application.Launch(processStartInfo);
TestStack.White.Application app = Application.Attach("winword");
TestStack.White.UIItems.WindowItems.Window window = app.GetWindow("Microsoft Word");
TestStack.White.UIItems.ListBoxItems.ComboBox whiteCombox = window.Get<ComboBox>(SearchCriteria.ByAutomationId("MyComboBox"));
var flaUiAutomationElment = new FlaUI.UIA2.UIA2FrameworkAutomationElement(new UIA2Automation(), whiteCombox.AutomationElement);
var flaUiComboBox = new FlaUI.Core.AutomationElements.ComboBox(flaUiAutomationElment);
I would suggest just doing everything in FlaUI if at all possible.
The answer is simple: Yes, because both solutins work on the same page, and that's Automation UI.
But you gonna need to inform to FLAUI what process ID you are dealing with, like below:
var automation = new UIA3Automation(); //start new instance of FALUI
var app = FlaUI.Core.Application.Attach(application.Process.Id); //.Id its a property of you var application
var window = app.GetMainWindow(automation); //With that, FlaUI gets hold of the window
After you deal with the FLAUI, you can attach the same ID on the White and vice-versa. It's pretty straight foward.
Related
The issue is related to Kendo UI's (dropdownlist, combobox, searchbox, etc) onfocusout and blur events, which close menu dropdowns when triggered, or if a browser window loses focus. In my case it was the WebDriver's GetScreenshot() method which calls an active focus on a screenshotted browser. With the parallel testing I'm taking screenshots using EventFiringWebDriver events. There are two windows of Edge/Chrome browser running in parallel and they are flashing constantly since GetScreenshot() is triggered. If Kendo UI element is opened in one of the windows, and the moment when flashing happens at the same time, it automatically triggers onfocusout and blur and dropdown closes. 40% of my tests were false negative because of that.
You can see the demo of the elements here: https://demos.telerik.com/kendo-ui/dropdownlist/index
I was able to overcome the issue with a multi-step solution. This works on Edge/Chrome 103+ and Selenium 4.1+
Firstly, I got rid of active focus calling by overring the GetScreenshot() method with a direct command to WebDriver.
public Screenshot GetScreenshot()
{
IHasCommandExecutor executor = Driver as IHasCommandExecutor;
var sessionId = ((WebDriver)Driver).SessionId; //if your driver is wrapped by any other class, you have to cast it to WebDriver first
var command = new HttpCommandInfo(HttpCommandInfo.PostCommand, $"/session/{sessionId}/chromium/send_command_and_get_result");
executor.CommandExecutor.TryAddCommand("Send", command); //try to create and add a command
var response = Send(executor, "Page.captureScreenshot", new JObject { { "format", "png" }, { "fromSurface", true } });
var base64 = ((Dictionary<string, object>)response.Value)["data"];
return new Screenshot(base64.ToString());
}
private Response Send(IHasCommandExecutor executor, string cmd, JObject args)
{
var json = new JObject { { "cmd", cmd }, { "params", args } };
var command = new Command("Send", json.ToString());
return executor.CommandExecutor.Execute(command); //execute the added command
}
Secondly, I found an extension for Chromium browsers, which disables Visibility API. There are a bunch of them, just search "Disable Visibility API" in Chrome Web Store. Apparently, it fakes 'activeness' of a browser window, so onfocusout and blur won't be firing anymore. Now you just have to include the extension when you're instantiating your driver:
var options = new EdgeOptions();
options.AddExtension("your path to extension"); //set your path
new DriverManager().SetUpDriver(new EdgeConfig(), VersionResolveStrategy.MatchingBrowser);
var service = EdgeDriverService.CreateDefaultService();
Driver = new EdgeDriver(edgeOptions);
In FLAUI trying to get a reference to a child element that starts with some letters or contains some for letters.
example start with or "DOC" or contains "DOC"
what I'm trying to do is that I'm opening some office files like doc,xls, ppt.
and want to attach the file as he is open to the screen.
foreach (var file in listOfFiles)
{
if (file.Name.Contains("DOC") || file.Name.Contains("PPT") || file.Name.Contains("XLS") || file.Name.Contains("TXT"))
{
file.AsButton().Invoke();
var window = new UIA3Automation();
desktopWindow = window.GetDesktop();
desktopWindow = WaitForElement(() => desktopWindow.FindFirstChild(cr => cr.ByName("// Here want to put name that start with ... or contains ...")));
var app = FlaUI.Core.Application.Attach(desktopWindow.Properties.ProcessId);
var application = app.GetMainWindow(new UIA3Automation());
CloseingProcess(application.Name);
img
If I understood you correctly, you want to check if a file that's already open has the extension you need. Correct?
For that, you have to get a hold of the window with FlaUI and with that you can check for the property .Title on the Window class, like below:
var automation = new UIA3Automation();
var app = FlaUI.Core.Application.Attach(application.Process.Id); //attach or start application here
var window = app.GetMainWindow(automation); //Get hold
window.Title //Use the .Title or .TitleBar property to check for your extension.
How can I use "sendkeys" or find new elements in a new opened browser window and return back to my old window?
Here is the code I have so far:
DesiredCapabilities EQcapabilities = new DesiredCapabilities();
EQcapabilities.SetCapability("appTopLevelWindow", EQWindowHandle);
var EQSession = new WindowsDriver<WindowsElement>(
new Uri("http://127.0.0.1:4723"), EQcapabilities);
// new window:
EQSession.FindElementByName("...").Click();
// I have tried this, but it is not working
String newWindowHandle = EQSession.WindowHandles.Last();
var newWindow = EQSession.SwitchTo().Window(newWindowHandle);
newWindow.sendkeys("some text");
You're sending the keys to the window. Find the element that you want to send them to first, and use SendKeys on that.
I'm trying to get user interaction with a background app through Cortana working for my app.
Whenever I do RequestDisambiguationAsync(response) Cortana just says that it ran into an error. However, it isn't breaking anywhere in Visual Studio.
Any ideas on what may be causing it? Below is the code that I am using:
var userPrompt = new VoiceCommandUserMessage();
string home1 = data.Structures[0].Name;
string home2 = data.Structures[1].Name;
userPrompt.DisplayMessage = "Which one did you want to set to home?";
userPrompt.SpokenMessage = String.Format("Which one did you want to set to home? {0} or {1}?", home1, home2);
var userReprompt = new VoiceCommandUserMessage();
userReprompt.DisplayMessage = "Which one did you want to set to home?";
userReprompt.SpokenMessage = "Which one did you want to set to home?";
var structuresContentTiles = new List<VoiceCommandContentTile>();
var structureTile = new VoiceCommandContentTile();
structureTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
structureTile.Title = home1;
structureTile.AppContext = data.Structures[0].Structure_id;
structuresContentTiles.Add(structureTile);
var structureTile2 = new VoiceCommandContentTile();
structureTile2.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
structureTile2.Title = home2;
structureTile.AppContext = data.Structures[1].Structure_id;
structuresContentTiles.Add(structureTile2);
var response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt, structuresContentTiles);
var voiceCommandDisambiguationResult = await voiceServiceConnection.RequestDisambiguationAsync(response);
This behavior can occur in some cases when you use
structureTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
but do not supply an image. Change it to VoiceCommandContentTileType.TitleOnly, or if you're supplying a Line1, use VoiceCommandContentTileType.TitleWithText, or provide an Image, and that should stop the failure from occurring.
I have C# code that creates a Visio Application instance, then opens some existing stencils so I can get the Shape Masters I need for my drawing. Visio 2013 changed things so I need 2 different stencils open. The issue is that I get 2 drawings open in Visio, 1 per stencil. When I build my document and save it, I can close it but there is still another empty drawing open. I also get an empty blank page in my active document where I am creating the drawing.
Visio.Application va = new Visio.Application();
va .Documents.Add(#"");
Visio.Documents vdocs = va.Documents;
const string templateNameU = "BASFLO_M.VSTX";
const string ConnectorStencilNameU = "BASFLO_M.VSSX";
const string RectangleStencilNameU = "BASIC_U.VSS";
const string stencilNameU = "CONNEC_U.VSSX";
const string connectorMasterNameU = "Dynamic Connector";
const string RectangleMasterNameU = "Rounded Rectangle";
Visio.Master connectorMaster = null;
Visio.Master rectangleMaster = null;
// open the templates we need
Visio.Document vc = vdocs.OpenEx(RectangleStencilNameU, short)Visio.VisOpenSaveArgs.visOpenDocked);
va.Documents.Add(templateNameU);
I have tried closing all the open drawings with:
foreach (Visio.Document d in va.Documents)
{
va.Documents[d.Name].Close();
}
va.ActiveDocument.Close();
but that is messy. The for loop for some reason doesn't close the active document. Is there a way to add multiple stencils to the same document and/or page so I am only working with one page? Is there a way to delete the blank page without resorting to a for loop to get the page name to delete it? I have looked through the API and don't see a way.
It looks like you are creating two documents.. i.e. the first (empty) one with va.Documents.Add("") and then the second one based on the template using va.Documents.Add(templateNameU).
If you don't want the first one, just don't create it.. Means, you can create new document, then open stencils, then draw, then close everything, like this:
var doc = va.Documents.Add(templateNameU)
var stn1 = va.Documents.Open(<first stencil>)
var stn2 = va.Documents.Open(<second stencil>)
// ... do stuff with the doc and then close everything...
doc.Close();
stn1.Close();
stn2.Close();
Am I missing something?
BTW, to get "Dynamic connector" you don't need to open the "Connector Stencil", it contains a specific dynamic connector. To get the default connector, you can just use Application.ConnectorToolDataObject
Also, you can connect shapes using shape.AutoConnect (this will also use the default connector)
Also, you don't need to open the stencil specifically actually. If it is part of the template, it will be opened automatically for you when you create a new drawing based on that template (so you can get them using Application.Documents[].
Maybe helpful? (draw 2 rectangles and connect them):
var doc = va.Documents.Add("BASICD_M.VSTX");
var stencil = va.Documents["BASIC_M.VSSX"];
var rectMaster = stencil.Masters["Rounded Rectangle"];
var rect1 = va.ActivePage.Drop(rectMaster, 1, 1);
var rect2 = va.ActivePage.Drop(rectMaster, 3, 1);
rect1.AutoConnect(rect2, Visio.VisAutoConnectDir.visAutoConnectDirNone);