All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.siwenyan.si.SiTest Maven / Gradle / Ivy

There is a newer version: 1.25.1.0
Show newest version
package com.github.siwenyan.si;

import com.github.siwenyan.common.Reporter;
import com.github.siwenyan.common.Sys;
import com.github.siwenyan.si.model.SiModelCommand;
import com.github.siwenyan.si.model.SiModelTest;
import org.apache.log4j.Logger;
import org.openqa.selenium.NoSuchWindowException;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class SiTest {
    private final static Logger LOGGER = Logger.getLogger(SiTest.class.getName());

    private final SiModelTest siModelTest;
    private List commandList = new ArrayList();
    private SiContext siContext;

    private int cursor;
    private int size;

    public SiTest(SiModelTest siModelTest, SiContext siContext) {
        this.siModelTest = siModelTest;
        this.siContext = siContext;
        init();
    }

    private void init() {

        int cmdIndex = 0; // zero based index because it's used to set the cursor
        Stack tracking = new Stack();
        for (SiModelCommand cmdM : this.siModelTest.getCommands()) {

            SiCommand cmd = SiCommand.createSiCommand(cmdM, this);
            this.commandList.add(cmd);

            cmd.setIndexInTest(cmdIndex++);
            switch (cmd.getCommand()) {
                case "times":
                    tracking.push(cmd);
                    break;
                case "while":
                    tracking.push(cmd);
                    break;
                case "if":
                    tracking.push(cmd);
                    break;
                case "else":
                    SiCommand popIf = tracking.pop();
                    if (!"if".equals(popIf.getSiModelCommand().getCommand())) {
                        throw new RuntimeException(cmd.toString() + " missing if in test: " + this.siModelTest.toString());
                    }
                    popIf.setPairInBack(cmd);
                    cmd.setPairInFront(popIf);
                    tracking.push(cmd);
                    break;
                case "end":
                    SiCommand popBegin = tracking.pop();
                    switch (popBegin.getSiModelCommand().getCommand()) {
                        case "times":
                        case "while":
                        case "if":
                        case "else":
                            break;
                        default:
                            throw new RuntimeException(cmd.toString() + " missing begin (times, while, if or else) in test: " + this.siModelTest.toString());
                    }
                    popBegin.setPairInBack(cmd);
                    cmd.setPairInFront(popBegin);
                    break;
                case "do":
                    tracking.push(cmd);
                    break;
                case "repeatIf":
                    SiCommand popDo = tracking.pop();
                    if (!"do".equals(popDo.getSiModelCommand().getCommand())) {
                        throw new RuntimeException(cmd.toString() + " missing do in test: " + this.siModelTest.toString());
                    }
                    popDo.setPairInBack(cmd);
                    cmd.setPairInFront(popDo);
                    break;
                default:
                    // do nothing
            }
        }

        if (tracking.size() > 0) {
            throw new RuntimeException(this.siModelTest.toString() + " missing ending for commands: " + tracking.toString());
        }

        this.size = this.commandList.size();

    }

    @Override
    public String toString() {
        return this.getSiModelTest().toString();
    }

    public boolean hasNextCommand() {
        return this.cursor < this.size;
    }

    public SiCommand nextCommand() {
        return this.commandList.get(this.cursor++);
    }

    public void run() {
        this.run(0, null, null);
    }

    public void run(int retry) {
        this.run(retry, null, null);
    }

    public void run(int retry, List> monitorModel, Map handlers) {
        Sys.out.start(SiTest.class.getName() + ".run");

        SiContextMonitor siContextMonitor = SiContextMonitor.buildMonitor(monitorModel, handlers);

        Reporter reporter = this.siContext.getReporter();

        try {
            this.siContext.addMonitor(siContextMonitor);
            this.siContext.stack(this);

            // the while(true) loop to control retires
            while (true) {
                SiCommand command = null;
                SiCommandExecutor executor = null;

                try {
                    //retry from beginning
                    this.reset();

                    reporter.start("test", "run", retry + "", "name", this.siModelTest.getName(),
                            "size", this.siModelTest.getCommands().size() + "");
                    Sys.out.start("test", "run", retry + "", "name", this.siModelTest.getName(),
                            "size", this.siModelTest.getCommands().size() + "");

                    this.siContext.event(new SiContextMonitorEvent(null, this, SiContextMonitorEvent.Type.BEFORE_TEST));
                    while (this.hasNextCommand()) {
                        command = this.nextCommand();
                        if ("run".equals(command.getCommand())) {
                            System.out.println("debug");
                        }

                        try {
                            reporter.start(command.getCommand(),
                                    "index", (command.getIndexInTest() + 1) + "",
                                    "target", command.getSiModelCommand().getTarget(),
                                    "value", command.getSiModelCommand().getValue(),
                                    "breadcrumb trail", this.siContext.getBreadcrumbTrail() + command.toString());
                            Sys.out.start(command.getCommand(), "breadcrumb trail", this.siContext.getBreadcrumbTrail() + command.toString());

                            executor = siContext.getExecutorManager().getExecutor(command);

                            try {
                                reporter.start("before");
                                Sys.out.start("before");

                                executor.beforeExecute(command, this.siContext);

                            } catch (SiWebDriverException e) {
                                reporter.reportWarning(e);

                                try {
                                    Sys.out.startAndEnd("trying to recover web driver", "e", e.getMessage());
                                    siContext.initWebDriver();
                                    retry++;
                                    Sys.out.startAndEnd("try one more time because the WebDriver is recovered", "retry", retry + "");
                                    throw e;
                                } catch (SiWebDriverException e1) {
                                    retry = -1;
                                    Sys.out.startAndEnd("no more retries because the WebDriver is not recovered", "retry", retry + "");
                                    throw e1;
                                }
                            } catch (Exception e) {
                                Sys.out.startAndEnd("exception ignored before command execution", "e", e.getMessage());
                                reporter.reportWarning(e);
                            } finally {
                                reporter.end("before");
                                Sys.out.end("before");
                            }

                            try {
                                reporter.start("execute");
                                Sys.out.start("execute");
                                this.siContext.event(new SiContextMonitorEvent(command, this, SiContextMonitorEvent.Type.BEFORE_COMMAND));
                                executor.execute(command, this.siContext);
                                this.siContext.event(new SiContextMonitorEvent(command, this, SiContextMonitorEvent.Type.AFTER_COMMAND));
                                siContext.getReporter().reportOK(command.toString());
                            } catch (SiVerifyException e) {
                                retry = 0;
                                Sys.out.startAndEnd("no more retries for verify exceptions", "retry", retry + "", "e", e.getMessage());
                                throw e;
                            } catch (NoSuchWindowException e) {
                                try {
                                    Sys.out.startAndEnd("trying to recover web driver", "e", e.getMessage());
                                    siContext.initWebDriver();
                                    retry++;
                                    Sys.out.startAndEnd("try one more time because the WebDriver is recovered", "retry", retry + "");
                                    throw e;
                                } catch (SiWebDriverException e1) {
                                    retry = -1;
                                    Sys.out.startAndEnd("no more retries because the WebDriver is not recovered", "retry", retry + "");
                                    throw e1;
                                }

                            } catch (Exception e) {
                                Sys.out.startAndEnd("raise exception for retry", "e", e.getMessage());
                                throw new RuntimeException(e.getMessage());
                            } finally {
                                reporter.end("execute");
                                Sys.out.end("execute");
                            }

                            try {
                                reporter.start("after");
                                Sys.out.start("after");
                                executor.afterExecute(command, this.siContext);
                            } catch (Exception e) {
                                Sys.out.startAndEnd("exception ignored after command execution", "e", e.getMessage());
                                reporter.reportWarning(e);
                            } finally {
                                reporter.end("after");
                                Sys.out.end("after");
                            }

                        } finally {
                            reporter.end(command.getCommand());
                            Sys.out.end(command.getCommand());
                        }

                    }
                    this.siContext.event(new SiContextMonitorEvent(null, this, SiContextMonitorEvent.Type.AFTER_TEST));

                    Sys.out.startAndEnd("success", "action", "breaking the while(true) loop to stop retry");
                    break;
                } catch (Exception e) {
                    Sys.out.startAndEnd("execution error", "e", e.getMessage(), "action", "embedding screenshot");
                    executor.embedScreenshot(command, this.siContext, e.getMessage());

                    Sys.out.startAndEnd("checking for retry", "retry", retry + "");
                    if (--retry < 0) {
                        Sys.out.startAndEnd("out of retires or not allowed to be retried",
                                "action1", "report the exception",
                                "action2", "breaking the while(true) loop by throwing a RuntimeException");
                        reporter.reportNG(e);
                        throw new RuntimeException(e);
                    } else {
                        Sys.out.startAndEnd("retry needed",
                                "action1", "this.getSiContext().setRetrying(true)",
                                "action2", "report the exception",
                                "action3", "without breaking the loop");
                        this.getSiContext().setRetrying(true);
                        reporter.reportWarning(e);
                    }
                } finally {
                    reporter.end("test");
                    Sys.out.end("test");
                }
            }
        } finally {
            this.siContext.unstack(this);
            this.siContext.removeMonitor(siContextMonitor);

            Sys.out.end(SiTest.class.getName() + ".run");
        }
    }

    private void reset() {
        this.setCursor(0);
    }

    public void setCursor(int pairIndex) {
        this.cursor = pairIndex;
    }

    public SiModelTest getSiModelTest() {
        return this.siModelTest;
    }

    public SiContext getSiContext() {
        return this.siContext;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy