4 votes

Vérifiez si un bouton est disponible ? si ce n'est pas le cas, attendez 5 secondes et vérifiez à nouveau ?

Essentiellement, je suis en train de voir si un bouton peut être cliqué pour le moment. Si ce n'est pas le cas, j'aimerais réessayer. J'ai donc besoin d'une sorte de fonction goto pour retourner à une ligne précédente de mon code. Bien que je soupçonne avoir écrit ceci de manière extrêmement mauvaise et que cela aurait pu être fait beaucoup plus facilement.

try {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
}catch (Exception e) {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}   

Pour contexte, voici le bouton en question.

2voto

SarojPurbey Points 248

Vous pouvez utiliser une attente fluide pour cela. Cela vérifiera si le bouton est cliquable toutes les 5 secondes pendant 30 secondes. Vous pouvez ajuster le temps selon vos besoins. Essayez ce code et donnez un retour si cela a fonctionné ou non.

 Wait wait = new FluentWait(driver)                           
                .withTimeout(30, TimeUnit.SECONDS)          
                .pollingEvery(5, TimeUnit.SECONDS)          
                .ignoring(NoSuchElementException.class);
        WebElement clickseleniumlink = wait.until(new Function(){

            public WebElement apply(WebDriver driver ) {
                return driver.findElement(By.xpath("//button[@id='btn_ok']"));
            }
        });
        clickseleniumlink.click();

1voto

KunduK Points 26770

Essayez cette manière, voyez si ça aide.

int size=driver.findElements(By.xpath("//button[@id='btn_ok']")).size();
if (size>0)
  {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
  }
  else
  {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    int size1=driver.findElements(By.xpath("//button[@id='btn_ok']")).size();
    if (size1>0)
  {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
  }
}

0voto

Guy Points 16347

Vous pouvez utiliser une attente explicite pour attendre que le bouton soit cliquable. Il va tester le bouton toutes les 500 ms pendant un temps spécifié maximum jusqu'à ce qu'il soit cliquable

WebDriverWait wait = new WebDriverWait(driver, 5); // temps d'attente maximum est de 5 ici, peut être configuré plus longtemps
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("btn_ok")));
button.click();

À noter, implicitlyWait définit le temps maximal pendant lequel le driver recherchera un élément, cela ne retarde pas le script.

0voto

Asyranok Points 894

Je préfère cela, car cela peut littéralement prendre n'importe quelle condition booléenne à "attendre jusqu'à".

    public static void WaitUntil(this IWebDriver driver, Func Condition, float timeout = 10f)
    {

        float timer = timeout;
        while (!Condition.Invoke() && timer > 0f) {

            System.Threading.Thread.Sleep(500);
            timer -= 0.5f;

        }
        System.Threading.Thread.Sleep(500);

    }

    driver.WaitUntil(() => driver.FindElements(By.XPath("quelque xPath...").Length == 0);

    //Voici l'avantage particulier par rapport aux attentes normales de Selenium. Pouvoir attendre des choses qui n'ont absolument rien à voir avec Selenium, mais qui sont parfois des choses valides à attendre.
    driver.WaitUntil(() => "Quelque chose existe dans la base de données");

Je trouve que l'attente implicite me pose plus de problèmes qu'elle n'en vaut la peine. Et je trouve que l'attente explicite de Selenium peut devenir un peu verbeuse, et elle ne couvre pas tout ce dont j'ai besoin dans mon framework, alors j'ai créé un certain nombre d'extensions. En voici une. Notez que j'utilise FindElements pour l'exemple ci-dessus car je ne veux pas qu'une exception soit levée si rien n'est trouvé. Cela devrait fonctionner pour vous.

Remarque : Ceci est en C#, mais il ne devrait pas être difficile de modifier cela pour n'importe quel autre langage (surtout Java). Si votre langage ne permet pas les extensions comme celle-ci, appelez simplement la méthode directement dans une classe. Vous devrez mettre ceci dans une classe statique pour qu'elle soit fonctionnelle. Soyez prudent lorsque vous étendez des classes existantes de cette manière dans la logique, car cela peut perturber les autres lorsqu'ils essaient de déterminer où les méthodes sont définies.

0voto

TheSociety Points 1498

Réponse rapide

Veuillez consulter le morceau de code ci-dessous et laissez-nous savoir s'il a résolu votre problème.

    public synchronized boolean clickOnButtonWhenItBecomesClickable() {
        boolean buttonClicked=false;
        try {
            List element = driver.findElements(By.xpath("//button[@id='btn_ok']"));

            while(element.size()!=0) {
                // si une action est nécessaire pour afficher le bouton, veuillez la faire.
                element = driver.findElements(By.xpath("//button[@id='btn_ok']"));
                if(element.size()!=0) {
                    wait = new FluentWait((WebDriver) driver).withTimeout(30, TimeUnit.SECONDS).pollingEvery(5,
                            TimeUnit.SECONDS);
                    wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath("//button[@id='btn_ok']"))));
                    buttonClicked=true;
                    break;  
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buttonClicked;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X