microsoft / WinAppDriver

Windows Application Driver
MIT License
3.65k stars 1.4k forks source link

Focus to Main application #1449

Open praveenvinnakota opened 3 years ago

praveenvinnakota commented 3 years ago

Hi,

Lets say I am in Main window(X) and when I click on button, a new window(Y) is opened. Now, the focus is shifted to the newly opened window(Y).

I want to focus to main window(X) to perform some operation, is there any way with winAppDriver?

Thanks, Praveen.

anunay1 commented 3 years ago

You need to create a root session and then switch to that window.

trashbat commented 3 years ago

Here's a Python snippet demonstrating how I would do it, the principle is the same for C# or whichever binding you're using:

# Open MS Edge (seems reasonable to assume it's installed due to minimum system requirements of WinAppDriver)
desired_caps = {"app": "MSEdge", "ms:waitForAppLaunch": "25"}

driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities=desired_caps)

# Store the initial window handle
initial_handle = driver.current_window_handle

edge_main_window = driver.find_element_by_tag_name("Window")

# Browse to Google, just so we can differentiate between windows
address_bar = edge_main_window.find_element_by_class_name("OmniboxViewViews")
address_bar.send_keys("https://google.com" + Keys.ENTER)

# Open a new window
edge_main_window.send_keys(Keys.CONTROL + "n")

# Now we have two windows open, with the focus on the new window. Switch back to the original Google window:
driver.switch_to.window(initial_handle)
praveenvinnakota commented 3 years ago

Hi, Here is my scenario: image

I have created a session for "Party Poker" and now I have clicked on button, which will open a new window(Amsterdam 70) under "Party Poker". Please refer the screenshot for reference. I am not able to switch my session from "Party Poker" to "Amsterdam 70" window, its throwing a "f0da4 is not a top level window handle" error. Also, please find the below code for reference:

_cap.setCapability("app", "Root"); desktopsession = new WindowsDriver(new URL("http://127.0.0.1:4723"), cap); System.out.println("Title : " + desktopsession.getTitle()); - This will get Desktop1

String topWindow = desktopsession.findElementByXPath("//[contains(@Name, 'Party Poker')]").getAttribute("NativeWindowHandle"); int MAWinHandleInt = Integer.parseInt(topWindow); String MAWinHandleHex = Integer.toHexString(MAWinHandleInt); cap.setCapability("appTopLevelWindow", MAWinHandleHex); DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability("appTopLevelWindow", MAWinHandleHex); session = new WindowsDriver(new URL("http://127.0.0.1:4723"), caps); System.out.println("Lobby title : " + session.getTitle()); - This will get Party Poker topWindow = desktopsession.findElementByXPath("//[contains(@Name, 'Amsterdam 162')]").getAttribute("NativeWindowHandle"); MAWinHandleInt = Integer.parseInt(topWindow); MAWinHandleHex = Integer.toHexString(MAWinHandleInt); session.switchTo().window(MAWinHandleHex); - Here its throwing error.._

anunay1 commented 3 years ago

What if you don't use the switch to option

praveenvinnakota commented 3 years ago

What if you don't use the switch to option

Its able to reconize the controls, but the problem here is, later I will open another window which will have window name="France 123".. and now I have 2 windows (Amsterdam 162 & France 123) and now if I try to find the control (lets say button 'Fold', this button will be there in both the windows). So, I am not sure in which window it will try to find the control.. thats the reason I want the create individual sessions to be created for both these windows.

praveenvinnakota commented 3 years ago

Hi Any update on the above issue :

I have created a session for PW window and started the script, lets say if I have 2 child windows (ABC & XYZ) under the parent window (PW). Is there a way to switch to ABC window, so that I can perform actions on this window. Idea here is to if I am able to switch ABC window, I need to switch XYZ window as well to perform actions on this screen.

Please.. any update on this issue is highly appreciated?

Thanks in advance, Praveen.

trashbat commented 3 years ago

If you can send me a minimal example of what you have already then I'll take a look, although I can't make any promises!

trashbat commented 3 years ago

P.S. I've just noticed that I'm tagged as a contributor to WinAppDriver, I just contributed a few lines of code to one of the sample tests that wasn't working for UK keyboard layouts.

praveenvinnakota commented 3 years ago

Hi John,

Here are the steps:

1 Step:

            cap.setCapability("app", "C:\\Program Files (x86)\\Programs\\Client.Desktop.exe");
    try
    {
        mainsession = new WindowsDriver(new URL("http://127.0.0.1:4723"), cap);
    }
    catch(MalformedURLException e)
    {
        e.printStackTrace();
    }
    mainsession.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

            System.out.println("Title : " + mainsession.getTitle());  // Let's say, here I get title as "MainAppWindow".

2 Step :

          mainsession.findElementByName("ABC")).click();
          Here, I click on a button "ABC", which will open a new window. Let's say window name is : ABC.

           mainsession.findElementByName("XYZ")).click();  (infact some times this action is also failing, because ABC window is in focus and MainAppWindow is back to ABC window)
          And again I click on another button "XYZ", which will open a new window. Let's say window name is : XYZ

          Here, both windows have same controls, just that window name is different.

          **Inspect .exe : MainAppWindow is parent and ABC, XYZ are child windows to MainAppWindow.**

          Now, my requirement is do actions in both the windows. 
          First, I have to click SUBMIT button in ABC window (NOTE : SUBMIT button is also there in XYZ window)
          mainsession.findElementByName("SUBMIT")).click() - This is success 

          Then, I have to focus on XYZ window and click on SUBMIT button (NOTE : SUBMIT button is again present in ABC window as well).
          mainsession.findElementByName("SUBMIT")).click() - This fails, trys to click SUBMIT in ABC window.

Hope, the scenario is clear. My main requirement is how to switch between those windows to do actions.

Thanks, Praveen.

trashbat commented 3 years ago

Thanks Praveen, I'll have a look this evening when I get some free time.

trashbat commented 3 years ago

I simulated your situation with a simple C# WPF application, the main window has two buttons named "ABC" and "XYZ" with the following click handler:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button clickedButton = (Button)sender;

    Window childWindow = new Window
    {
        Title = clickedButton.Name,
        Height = 100,
        Width = 200,
        Owner = this
    };

    Button submitButton = new Button
    {
        Content = "Submit",
        Name = "Submit",
        Height = 20,
        Width = 100
    };

    Grid grid = new Grid();

    grid.Children.Add(submitButton);

    childWindow.Content = grid;

    clickedButton.IsEnabled = false;
    childWindow.Show();
}

So clicking on a button will create a new window, with the same title as the button. I'm not a .NET developer, I'm sure there are better ways of achieving this.

My Java code contains the following, and all of the buttons are clicked for me:

mainSession.findElementByName("ABC").click();
mainSession.findElementByName("XYZ").click();

WebElement abcWindow = mainSession.findElementByXPath("//Window[@Name='ABC']");
WebElement xyzWindow = mainSession.findElementByXPath("//Window[@Name='XYZ']");

abcWindow.findElement(By.name("Submit")).click();
xyzWindow.findElement(By.name("Submit")).click();