Create execution looping until an element is visible

Asked

Viewed 210 times

0

I need to make a looping in which it stops running only when a specific element becomes visible.
It must click the filter button and check if the element is visible, if the return is false, it performs the process again. If the return is true, it will enter the IF I will create.
I don’t know if I need to use while with a for or another function...

Follow the code I have at the moment.

//CLICA EM FILTRAR E ESPERA O STATUS FINALIZADO COM SUCESSO
        dsl.clicarBotao("ctl00_ctl00_placeHolderMain_mainWebCad_btnFiltrar");
        Thread.sleep(1500);
        String statusAssincProcess = "Iniciado";
        String statusAssincProcess2 = "Sucesso";

        while ("Iniciado".equals(statusAssincProcess) || "Sucesso".equals(statusAssincProcess2)){
            Thread.sleep(2500);
            dsl.clicarBotao("ctl00_ctl00_placeHolderMain_mainWebCad_btnFiltrar");
            Thread.sleep(1500);

            statusAssincProcess = dsl.obterTexto(By.xpath(
                    "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
            statusAssincProcess2 = dsl.obterTexto(By.xpath(
                    "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));

            if ("Finalizado".equals(statusAssincProcess) || "Erro".equals(statusAssincProcess2)) {
                    Screenshot.tirar(navegador, "C:\\Users\\servflex050\\Documents\\TST_FATL\\printscreen\\"
                            + nomeTeste + "_" + Generator.dataHoraparaArquivo() + ".png");
                statusAssincProcess = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
                statusAssincProcess2 = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));
            }
            if ("Finalizado".equals(statusAssincProcess) || "Sucesso".equals(statusAssincProcess2)){

                Screenshot.tirar(navegador, "C:\\Users\\servflex050\\Documents\\TST_FATL\\printscreen\\"
                        + nomeTeste + "_" + Generator.dataHoraparaArquivo() + ".png");
                statusAssincProcess = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
                statusAssincProcess2 = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));
                }
            }

2 answers

1

Stop executing ONLY when you find it can take you to a code running endlessly, I advise you to put a time limit.

Now on to your question, by my understanding of what you want to do, a do while is more than enough, and your code is very redundant in its actions it seems, your code does this:

clica no botao
espera 1.5 segundos
atribui o status1
atribui o status2

enquanto status1 == 'iniciado' OU status2 == 'sucesso' // Essa logica não faz sentido com o que você quer, você quer que espere enquanto NÃO for finalizado com sucesso, o problema é que se ele for finalizado com sucesso ele vai continuar executando isso aqui, pois finalizado com sucesso vai dar true no status2.

    espera 2.5 segundos //esperando porque? você não teve ação desde a ultima espera, e você não precisa ficar esperando por tempo fixo assim!
    clica no botao novamente //você não fez nada com o ultimo estado, porque ta clicando novamente ?
    pega o status1 da tela
    pega o status2 da tela

    se status1 == 'finalizado' OU status2 == 'erro'
        tira um print
        pega o status1 da tela //porque pegar de novo se você acabou de pegar?
        pega o status2 da tela //porque pegar de novo se você acabou de pegar?

    se status1 == 'finalizado' OU status == 'sucesso' //não é só jogar o 'OU status == sucesso' no 'se' de cima?
        tira um print          //print redundante
        pega o status1 da tela //porque pegar de novo se você acabou de pegar?
        pega o status2 da tela //porque pegar de novo se você acabou de pegar?

In my mind it would make more sense like this:

cria o status1
cria o status2

faca
    clica no botao
    pega o status1 da tela
    pega o status2 da tela

    se status1 == 'finalizado' OU status2 == 'erro' OU status2 == 'sucesso'
        tira um print
enquanto status1 = 'iniciado' E status2 = 'sucesso'

Java result:

String statusAssincProcess;
String statusAssincProcess2;

do{
    dsl.clicarBotao("ctl00_ctl00_placeHolderMain_mainWebCad_btnFiltrar");
    statusAssincProcess = dsl.obterTexto(By.xpath("//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
    statusAssincProcess2 = dsl.obterTexto(By.xpath("//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));

    if ("Finalizado".equals(statusAssincProcess) || "Erro".equals(statusAssincProcess2) || "Sucesso".equals(statusAssincProcess2)) {
        Screenshot.tirar(navegador, "C:\\Users\\servflex050\\Documents\\TST_FATL\\printscreen\\" + nomeTeste + "_" + Generator.dataHoraparaArquivo() + ".png");
    }

} while("Iniciado".equals(statusAssincProcess) && "Sucesso".equals(statusAssincProcess2));

Since you have the dsl ( To what I think this dsl would be an Object page right? ) in the middle of the way he MUST wait for the availability of the elements, you should not go around punching Thread.Leep() to and fro.

If the element is "always" in the DOM:

public String obterTexto(By locator) {
  WebElement element = new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfElementLocated(locator));
  return element.getText()
}

And in case the element takes LONG to be ADDED in DOM, you can use this one:

public String obterTexto(By locator) {
  WebElement element = new WebDriverWait(driver, 30)
    .ignoring(NoSuchElementException.class)
    .until(ExpectedConditions.visibilityOfElementLocated(locator));
  return element.getText()
}
  • First, thanks for the comments, just so I realized how polluted my code was. Now it’s much better! I couldn’t really explain what I need, but I think it’ll be easier to understand. And insert the data into the filters on the screen and click the "filter" button to show a grid with the processes and their status. For the grid to appear, you need to run an internal process on the server that can take up to 3 minutes, so I need the grid to appear on the screen first. After that I do all this status check. I think it’s now clearer.

  • The grid appears with status1 "started" and Status2 "success". After finishing they are changed to status1 "finished" and Status2 "successful" or "error". Then the status execution will be done until they are different from "started" and "successful".

  • 1

    Okay, with the code that I passed on, I believe that you can achieve your goal, you populate the fields and then run those lines of code, that should cover your goal, that do while, in my example then it will stop repeating once the status is finished + success, but it is not what you really want, in which case you should change the last line to while("iniciado".equals(statusAssincProcess) && "sucesso".equals(statusAssincProcess2)); I’ll edit the answer to cover it.

  • And watch out for uppercase or lowercase.

  • When I click filter and the grid is not yet available, it will not return the execution error when trying to pass the status to the variables?

  • I edited the end of the answer and added how to stop using Thread.Sleep, you should make use of Webdriverwait in your class dsl.

  • The code perfectly solves the treatment of status and Sleep, but it still does not solve the question of the element I need to verify. I need to click search (button id=xyz) check whether the element id=abc is visible on the page. If it is visible, I have a true and follow with the script if the return is false, i do the run of "click search", and "check element" again.

Show 3 more comments

0


I was able to solve the loop part to check the element on the page with this code.

        //VERIFICA SE EXISTE PROCESSOS ASSINCRONOS NA GRID
        String statusAssincProcess;
        String statusAssincProcess2;

        while (true) {
            WebElement grid;
            try {
                dsl.clicarBotao("ctl00_ctl00_placeHolderMain_mainWebCad_btnFiltrar");
                grid = navegador.findElement(By.id(
                        "ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_btnDownloadCSV"));
            } catch (NoSuchElementException ex) {
                continue;
            }
            if (grid.isDisplayed()) {
                break;
            }
        }

        //VERIFICA STATUS PROCESSO ASSINCRONO - CREDITOS AO SPENCER
        do {
            statusAssincProcess = dsl.obterTexto(By.xpath(
                    "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
            statusAssincProcess2 = dsl.obterTexto(By.xpath(
                    "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));

            if ("Finalizado".equals(statusAssincProcess) && "Erro".equals(statusAssincProcess2)
                    || "Sucesso".equals(statusAssincProcess2)) {
                Screenshot.tirar(navegador, "C:\\Users\\servflex050\\Documents\\TST_FATL\\printscreen\\"
                        + nomeTeste + "_" + Generator.dataHoraparaArquivo() + ".png");
                statusAssincProcess = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbStatus\"]"));
                statusAssincProcess2 = dsl.obterTexto(By.xpath(
                        "//*[@id=\"ctl00_ctl00_placeHolderMain_mainWebCad_grdServiceStatus_ctl00_ctl04_lbFinalizadoComErro\"]"));
            }
        } while("Iniciado".equals(statusAssincProcess) && "Sucesso".equals(statusAssincProcess2));
        System.out.print("Processo de " + nomeTeste + statusAssincProcess + " com " + statusAssincProcess2);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.