it-swarm.com.de

Wie kann der Selenium-Webtreiber erfahren, wann das neue Fenster geöffnet wurde, und seine Ausführung fortsetzt

Ich habe ein Problem mit der Automatisierung einer Webanwendung mit dem Selenium-Webtreiber.

Die Webseite hat eine Schaltfläche, die beim Anklicken ein neues Fenster öffnet. Wenn ich den folgenden Code verwende, wird OpenQA.Selenium.NoSuchWindowException: No window found ausgegeben. 

WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();

Um das obige Problem zu lösen, füge ich Thread.Sleep(50000); zwischen den Schaltflächenklick- und SwitchTo-Anweisungen hinzu.

WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
Thread.Sleep(50000); //wait
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();

Das Problem wurde behoben, aber ich möchte nicht die Thread.Sleep(50000);-Anweisung verwenden. Wenn das Fenster mehr Zeit zum Öffnen benötigt, kann Code ausfallen. Wenn sich das Fenster schnell öffnet, wird der Test unnötig langsam. 

Gibt es eine Möglichkeit zu wissen, wann sich das Fenster geöffnet hat und der Test seine Ausführung fortsetzen kann?

23
Ozone

Sie müssen das Steuerelement in ein Popup-Fenster umschalten, bevor Sie Vorgänge ausführen können. Auf diese Weise können Sie Ihr Problem lösen.

Bevor Sie das Popup-Fenster öffnen, rufen Sie das Handle des Hauptfensters auf und speichern Sie es.

String mwh=driver.getWindowHandle();

Versuchen Sie nun, das Popup-Fenster durch Ausführen einer Aktion zu öffnen:

driver.findElement(By.xpath("")).click();

Set s=driver.getWindowHandles(); //this method will gives you the handles of all opened windows

Iterator ite=s.iterator();

while(ite.hasNext())
{
    String popupHandle=ite.next().toString();
    if(!popupHandle.contains(mwh))
    {
        driver.switchTo().window(popupHandle);
        /**/here you can perform operation in pop-up window**
        //After finished your operation in pop-up just select the main window again
        driver.switchTo().window(mwh);
    }
}
28
Santoshsarma

Sie könnten warten, bis die Operation erfolgreich ist, z. B. in Python:

from Selenium.common.exceptions    import NoSuchWindowException
from Selenium.webdriver.support.ui import WebDriverWait

def found_window(name):
    def predicate(driver):
        try: driver.switch_to_window(name)
        except NoSuchWindowException:
             return False
        else:
             return True # found window
    return predicate

driver.find_element_by_id("id of the button that opens new window").click()        
WebDriverWait(driver, timeout=50).until(found_window("new window name"))
WebDriverWait(driver, timeout=10).until( # wait until the button is available
    lambda x: x.find_element_by_id("id of button present on newly opened window"))\
    .click()
10
jfs

Ich verwende das, um zu warten, bis das Fenster geöffnet wird und es funktioniert für mich.

C # -Code:

public static void WaitUntilNewWindowIsOpened(this RemoteWebDriver driver, int expectedNumberOfWindows, int maxRetryCount = 100)
    {
        int returnValue;
        bool boolReturnValue;
        for (var i = 0; i < maxRetryCount; Thread.Sleep(100), i++)
        {
            returnValue = driver.WindowHandles.Count;
            boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
            if (boolReturnValue)
            {
                return;
            }
        }
        //try one last time to check for window
        returnValue = driver.WindowHandles.Count;
        boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
        if (!boolReturnValue)
        {
            throw new ApplicationException("New window did not open.");
        }
    }

Und dann nenne ich diese Methode im Code

Extensions.WaitUntilNewWindowIsOpened(driver, 2);
1
DadoH

Endlich fand ich die Antwort. Ich benutzte die folgende Methode, um zum neuen Fenster zu wechseln.

public String switchwindow(String object, String data){
        try {

        String winHandleBefore = driver.getWindowHandle();

        for(String winHandle : driver.getWindowHandles()){
            driver.switchTo().window(winHandle);
        }
        }catch(Exception e){
        return Constants.KEYWORD_FAIL+ "Unable to Switch Window" + e.getMessage();
        }
        return Constants.KEYWORD_PASS;
        }

Um zum übergeordneten Fenster zu gelangen, habe ich folgenden Code verwendet:

 public String switchwindowback(String object, String data){
            try {
                String winHandleBefore = driver.getWindowHandle();
                driver.close(); 
                //Switch back to original browser (first window)
                driver.switchTo().window(winHandleBefore);
                //continue with original browser (first window)
            }catch(Exception e){
            return Constants.KEYWORD_FAIL+ "Unable to Switch to main window" + e.getMessage();
            }
            return Constants.KEYWORD_PASS;
            }

Ich denke, das wird dir helfen, zwischen den Fenstern zu wechseln.

1
Prasanna

Obwohl diese Frage bereits beantwortet wurde, war keine von ihnen für mich wirklich nützlich, da ich mich nicht darauf verlassen kann, ein neues Fenster zu erhalten. Ich musste noch mehr filtern. Ich fing an, die Lösung von Dadoh zu verwenden, verbesserte sie jedoch, bis ich diese Lösung fand Ich hoffe, es ist für jemanden von Nutzen.

public async Task<string> WaitUntilNewWindowIsOpen(string expectedWindowTitle, bool switchToWindow, int maxRetryCount = 100)
{
    string newWindowHandle = await Task.Run(() =>
    {
        string previousWindowHandle = _driver.CurrentWindowHandle;
        int retries = 0;
        while (retries < maxRetryCount)
        {
            foreach (string handle in _driver.WindowHandles)
            {
                _driver.SwitchTo().Window(handle);
                string title = _driver.Title;
                if (title.Equals(expectedWindowTitle))
                {
                    if(!switchToWindow)
                        _driver.SwitchTo().Window(previousWindowHandle);
                    return handle;
                }
            }
            retries++;
            Thread.Sleep(100);
        }
        return string.Empty;
    });
    return newWindowHandle;
}

Bei dieser Lösung habe ich mich entschieden, den erwarteten Fenstertitel als Argument für die Funktion zu übergeben, um alle Fenster zu durchlaufen und den neuen Fenstertitel zu vergleichen. Auf diese Weise wird garantiert das korrekte Fenster zurückgegeben. Hier ist ein Beispielaufruf für diese Methode:

await WaitUntilNewWindowIsOpen("newWindowTitle", true);
0
HeD_pE