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

com.github.siwenyan.si.SiContext 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.common.StringUtils;
import com.github.siwenyan.si.model.SiModel;
import com.github.siwenyan.si.model.SiModelCommand;
import com.github.siwenyan.si.model.SiModelTest;
import com.github.siwenyan.si.model.VarExpression;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.security.UserAndPassword;

import java.util.*;
import java.util.regex.Matcher;

public class SiContext {
    private static final Logger log = Logger.getLogger(SiContext.class.getName());

    private final static Random r = new Random(System.currentTimeMillis());
    private final static String CALC_KEY_SIDE_TIMESTAMP = "Side.timestamp";
    private final static String CALC_KEY_SIDE_RANDOM2 = "Side.random2";
    private final static String CALC_KEY_SIDE_RANDOM3 = "Side.random3";
    private final static String CALC_KEY_SIDE_RANDOM5 = "Side.random5";
    private final static String CALC_KEY_SIDE_RANDOM7 = "Side.random7";
    private final static List CALC_KEYS = Arrays.asList(new String[]{
            CALC_KEY_SIDE_TIMESTAMP,
            CALC_KEY_SIDE_RANDOM2,
            CALC_KEY_SIDE_RANDOM3,
            CALC_KEY_SIDE_RANDOM5,
            CALC_KEY_SIDE_RANDOM7
    });

    private final SiModel siModel;
    private final ISiWebDriverFactory factory;
    private WebDriver driver;
    private JavascriptExecutor javascriptExecutor;
    private Capabilities cap;
    private Reporter reporter = new Reporter();
    private Map vars = new HashMap() {
        @Override
        public Set keySet() {
            Set keySet = new HashSet(super.keySet());
            keySet.addAll(CALC_KEYS);
            return keySet;
        }

        @Override
        public boolean containsKey(Object key) {
            return super.containsKey(key) || CALC_KEYS.contains(key);
        }

        @Override
        public String get(Object key) {
            if (super.containsKey(key)) {
                return super.get(key).toString();
            } else {
                String sKey = key.toString();
                switch (sKey) {
                    case CALC_KEY_SIDE_TIMESTAMP:
                        return Reporter.getTimestamp();
                    case CALC_KEY_SIDE_RANDOM2:
                        return "" + (10 + r.nextInt(90));
                    case CALC_KEY_SIDE_RANDOM3:
                        return "" + (100 + r.nextInt(900));
                    case CALC_KEY_SIDE_RANDOM5:
                        return "" + (10000 + r.nextInt(90000));
                    case CALC_KEY_SIDE_RANDOM7:
                        return "" + (1000000 + r.nextInt(9000000));
                    default:
                        return null;
                }
            }
        }
    };

    private Map testByName = new HashMap();
    private Stack siTestStack = new Stack();

    private int winSerNo = 0;
    private Map winSer = new HashMap();
    private ExecutorManager executorManager = ExecutorManager.getInstance();
    private Map alertHow = new HashMap();
    private Set siContextMonitors = new HashSet();
    private ISiReporter siReporter;
    private boolean isRetrying;
    private String siContextName;
    private boolean demoing = false;

    public SiContext(SiModel siModel, ISiWebDriverFactory factory) {
        if (null == siModel) {
            throw new RuntimeException("siModel cannot be null");
        }
        this.siModel = siModel;

        for (SiModelTest test : this.siModel.getTests()) {
            this.testByName.put(test.getName(), new SiTest(test, this));
        }

        this.addVar("KEY_ENTER", Keys.ENTER);
        this.addVar("Side.start.uuid", UUID.randomUUID().toString());
        this.addVar("Side.start.timestamp", Reporter.getTimestamp());
        this.addVar("Side.today", Reporter.mmDdYyyy());
        this.addVar("Side.today_yesterday", Reporter.mmDdYyyy(-1, Calendar.DATE));
        this.addVar("Side.today_next_year", Reporter.mmDdYyyy(1, Calendar.YEAR));

        this.factory = factory;

    }

    public SiContext(SiContext siContext) {
        this(new SiModel(siContext.siModel), siContext.factory);
        this.cap = siContext.cap;
        this.driver = siContext.driver;
        this.javascriptExecutor = siContext.javascriptExecutor;
        this.reporter = siContext.reporter;
        this.vars.putAll(siContext.getVars());

        this.winSer.putAll(siContext.winSer);
        this.alertHow.putAll(siContext.alertHow);

        this.siReporter = siContext.siReporter;
        this.isRetrying = siContext.isRetrying;
        this.demoing = siContext.demoing;
    }

    public void initWebDriver() throws SiWebDriverException {
        this.driver = this.factory.getWebDriver();
        this.javascriptExecutor = (JavascriptExecutor) this.driver;
        this.cap = ((RemoteWebDriver) driver).getCapabilities();

        this.setRetrying(false);

        String url = this.siModel.getUrl();
        if (null != url && !url.isEmpty()) {
            this.driver.get(url);
        }
    }

    public SiModel getSiModel() {
        return this.siModel;
    }

    public WebDriver asWebDriver() throws SiWebDriverException {
        if (null == this.driver) {
            try {
                initWebDriver();
            } catch (Exception e) {
                throw new SiWebDriverException(e);
            }
        }
        return driver;
    }

    public JavascriptExecutor asJavascriptExecutor() throws SiWebDriverException {
        if (null == this.javascriptExecutor) {
            try {
                initWebDriver();
            } catch (Exception e) {
                throw new SiWebDriverException(e);
            }
        }
        return this.javascriptExecutor;
    }

    public boolean isIE() {
        return "internet explorer".equalsIgnoreCase(this.cap.getBrowserName());
    }

    public void setSiReporter(ISiReporter siReporter) {
        this.siReporter = siReporter;
    }

    public ISiReporter getSiReporter() {
        return siReporter;
    }

    public By by(String target) {
        target = this.dynamic(target, "", "");
        String[] p = target.split("=", 2);
        String sBy = p[1];
        switch (p[0]) {
            case "id":
                return By.id(sBy);
            case "name":
                return By.name(sBy);
            case "linkText":
                return By.linkText(sBy);
            case "xpath":
                return By.xpath(sBy);
            case "css":
                return By.cssSelector(sBy);
            default:
                return By.xpath(target);
        }
    }

    public String dynamic(String s, String prefex, String suffix, Map... moreVarsArray) {
        String s0 = s;

        prefex = null == prefex ? "" : prefex.trim();
        suffix = null == suffix ? "" : suffix.trim();
        Matcher matcher = VarExpression.pattern.matcher(s);
        Map invalidRefById = new HashMap();
        while (matcher.find()) {
            String name = matcher.group(2);
            String value = this.getVarValue(name, moreVarsArray);
            if (null != value) {
                s = matcher.replaceFirst(prefex + value + suffix);
            } else {
                throw new RuntimeException("Undefined variable: " + name);
            }
            matcher = VarExpression.pattern.matcher(s);
        }
        if (!s.equals(s0)) {
            this.getReporter().reportMessage("dynamic: " + s);
        }
        return StringUtils.peel(s);
    }

    private String getVarValue(String name, Map[] moreVarsArray) {
        if (this.vars.containsKey(name)) {
            Object o = this.vars.get(name);
            return null == o ? null : o.toString();
        }
        for (Map moreVars : moreVarsArray) {
            if (moreVars.containsKey(name)) {
                Object o = moreVars.get(name);
                return null == o ? null : o.toString();
            }
        }
        return null;
    }

    public void addVar(String name, Object value) {
        this.vars.put(name, value);
    }

    public String getUrl() {
        String url = this.siModel.getUrl();
        if (null == url || url.trim().isEmpty()) {
            return "";
        } else {
            url = this.dynamic(url, "", "");
            url = url.substring(0, url.indexOf('/', "https://".length()));
            return url;
        }
    }

    public SiTest getTestByName(String name) {
        Sys.out.startAndEnd(this.getClass().getName() + "getTestByName", "name", name);
        return this.testByName.get(name);
    }

    public Reporter getReporter() {
        return this.reporter;
    }

    public ExecutorManager getExecutorManager() {
        return this.executorManager;
    }

    public void clearAlert() {
        try {
            Alert alert = this.asWebDriver().switchTo().alert();
            String alertText = alert.getText();
            Sys.out.reportMessage(">>>>>ALERT: " + alertText);

            String how = "";
            for (String partialAlert : this.alertHow.keySet()) {
                if (alertText.contains(partialAlert)) {
                    how = alertHow.get(partialAlert);
                    break;
                }
            }

            if (null != how) {
                boolean processed = true;
                if ("dismiss".equals(how)) {
                    alert.dismiss();
                    Sys.out.reportMessage("Dismissed");
                } else if ("accept".equals(how)) {
                    alert.accept();
                    Sys.out.reportMessage("Accepted");
                } else if (how.startsWith("authenticateUsing")) {
                    String[] p = how.split("|", 3);
                    alert.authenticateUsing(new UserAndPassword(p[1], p[2]));
                    Sys.out.reportMessage("Authentication Used");
                } else {
                    processed = false;
                }
                if (processed) {
                    Thread.sleep(5000);
                }
            }

        } catch (Exception e) {
            //do nothing
        }
    }

    public void putAlertHow(String partialAlert, String how) {
        this.alertHow.put(partialAlert, how);
    }

    @Nullable
    public String getVarValue(String varName) {
        return this.vars.containsKey(varName) ? this.vars.get(varName).toString() : null;
    }

    public void quit() {
        try {
            this.driver.manage().deleteAllCookies();
            this.driver.quit();
        } catch (Exception e) {
            // do nothing
        }
    }

    public void addMonitor(SiContextMonitor siContextMonitor) {
        this.siContextMonitors.add(siContextMonitor);
    }

    public void removeMonitor(SiContextMonitor siContextMonitor) {
        this.siContextMonitors.remove(siContextMonitor);
    }

    private Set cloneSiContextMonitors() {
        return new HashSet(this.siContextMonitors);
    }

    public void event(SiContextMonitorEvent event) {
        switch (event.getType()) {
            case BEFORE_COMMAND:
            case AFTER_COMMAND:
                //ignore command events
                return;
        }

        this.siContextMonitors.remove(null);
        if (this.siContextMonitors.isEmpty()) {
            return;
        }
        try {
            this.getReporter().start("event", "name", event.getName());
            boolean handled = false;
            for (SiContextMonitor monitor : this.cloneSiContextMonitors()) {
                try {
                    this.getReporter().start("dispatch", "monitor", monitor.toString());
                    monitor.dispatch(event);
                    handled = true;
                } catch (UnhandledEventException e) {
                    // do nothing
                } finally {
                    this.getReporter().end("dispatch");
                }
            }

            if (!handled) {
                String msg = "Unhandled event: " + event.toString();
                throw new RuntimeException(msg);
            }
        } finally {
            this.getReporter().end("event");
        }
    }

    public SiTest asTest(SiModelCommand... cmds) {
        return this.asTest(Arrays.asList(cmds));
    }

    public SiTest asTest(List cmds) {
        Sys.out.startAndEnd(this.getClass().getName() + "asTest", "at", "start");
        SiModelTest siModelTest = SiModelProvider.randomSiModelTest(cmds);
        this.siModel.getTests().add(siModelTest);

        String testName = siModelTest.getName();
        SiTest siTest = new SiTest(siModelTest, this);
        this.testByName.put(testName, siTest);

        try {
            this.siModel.reIndex();
            this.siModel.syntaxCheck();
        } catch (Exception e) {
            Sys.out.startAndEnd(this.getClass().getName() + "asTest", "at", "this.siModel.reIndex() or this.siModel.syntaxCheck()", "e", e.getMessage());
            throw e;
        }
        Sys.out.startAndEnd(this.getClass().getName() + "asTest", "at", "end");
        return siTest;
    }

    public SiTest groupTestByNames(String... names) {
        Sys.out.startAndEnd(this.getClass().getName() + "groupTestByNames", "at", "start");
        List cmds = new ArrayList();
        for (String name : names) {
            if (null == this.getTestByName(name)) {
                String err = "No such test: " + name + " in group: " + Arrays.asList(names);
                Sys.out.startAndEnd("check the test names", "e", err);
                throw new RuntimeException(err);
            } else {
                SiModelCommand cmd = new SiModelCommand();
                cmd.setCommand("run");
                cmd.setTarget(name);

                cmds.add(cmd);
            }
        }
        Sys.out.startAndEnd(this.getClass().getName() + "groupTestByNames", "at", "end");
        return this.asTest(cmds);
    }

    public String takingCommandScreenshots(SiModelCommand siModelCommand) {
        if ("true".equalsIgnoreCase(this.getVarValue("config.siContext.takingCommandScreenshots"))) {
            return this.getVarValue("config.siContext.takingCommandScreenshots." + siModelCommand.getCommand());
        }
        return "none";
    }

    public void stack(SiTest siTest) {
        this.siTestStack.push(siTest);
    }

    public void unstack(SiTest siTest) {
        SiTest st = this.siTestStack.pop();
        if (siTest != st) {
            throw new RuntimeException("Unmatched stack: expected " + siTest + ", actual " + st);
        }
    }

    public boolean isRetrying() {
        return this.isRetrying;
    }

    public void setRetrying(boolean isRetrying) {
        this.isRetrying = isRetrying;
    }

    public void setDemoing(boolean demoing) {
        this.demoing = demoing;
    }

    public boolean isDemoing() {
        return this.demoing;
    }

    public String getBreadcrumbTrail() {
        String s = "";
        for (SiTest siTest : this.siTestStack) {
            s += siTest.getSiModelTest().getName();
            s += " | ";
        }
        return s;
    }

    public Map getVars() {
        return this.vars;
    }

    public void setContextName(String siContextName) {
        this.siContextName = siContextName;
    }

    public String getContextName() {
        return this.siContextName;
    }

    public void setPauseFactor(float pauseFactor) {
        ((SiCommandExecutorPause) this.executorManager.getBasicExecutor("pause")).setPauseFactor(pauseFactor);
    }

    public void addMonitor(String jsonStringOrJsonFilePath, Map handlers) {
        this.addMonitor(SiContextMonitor.buildMonitor(jsonStringOrJsonFilePath, handlers));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy