com.github.siwenyan.superglue.team.TeamBase Maven / Gradle / Ivy
package com.github.siwenyan.superglue.team;
import com.github.siwenyan.common.ImmediateAbortException;
import com.github.siwenyan.common.Retry;
import com.github.siwenyan.common.StringTools;
import com.github.siwenyan.common.Sys;
import com.github.siwenyan.superglue.AbstractStepSet;
import com.github.siwenyan.superglue.Login;
import com.github.siwenyan.web.LostBrowserException;
import com.github.siwenyan.web.WebUtils;
import cucumber.api.Scenario;
import org.apache.log4j.Logger;
import org.junit.Assert;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Queue;
public abstract class TeamBase extends AbstractStepSet {
private static final Logger log = Logger.getLogger(TeamBase.class.getName());
protected final Map pf;
private final String objectNameKey;
protected Map> outcome = new LinkedHashMap<>();
private long teamworkTimeoutInMillis = Integer.parseInt(Sys.conf.getProperty("teamworkTimeoutInMinutes")) * 60 * 1000;
public TeamBase(Scenario scenario, Map pf, String objectNameKey) throws LostBrowserException {
super(scenario, Login.login(scenario, pf));
this.pf = pf;
this.objectNameKey = objectNameKey;
}
protected abstract Queue buildTeam(Map pf);
protected abstract void kickOff();
protected abstract void immediateRecover();
public Map> getOutcome() {
return this.outcome;
}
public final boolean teamwork() {
return teamwork(teamworkTimeoutInMillis);
}
public final boolean teamwork(long teamworkTimeoutInMillis) {
boolean success = new Retry("teamwork>" + StringTools.shortName(this.getClass()), teamworkTimeoutInMillis, 0, 0) {
@Override
protected void tryOnce() throws Exception {
try {
if ("true".equalsIgnoreCase(Sys.conf.getProperty("team.retryWithNewBrowser"))) {
Login.quitScenarioLogins(scenario());
}
LinkedHashMap pfWorking = new LinkedHashMap<>(pf);
setDriver(Login.login(scenario(), pfWorking));
Queue team = buildTeam(pfWorking);
stopAtNextPageBegin(pfWorking, team);
String continueFromPage = pfWorking.get(PageWorkerBase.CONTINUE_FROM_PAGE);
if (!StringTools.isEmpty(continueFromPage)) {
while (null != team.peek() && !team.peek().getPageName().contains(continueFromPage)) {
team.poll();
}
}
Assert.assertTrue("No workers.", !team.isEmpty());
outcome.clear();
teamworkInQueue(team);
} catch (StopAtPageBeginException e) {
scenarioLogger.warn("Stop at page begin: " + e.getMessage());
} catch (StopAtPageException e) {
scenarioLogger.warn("Stop at page: " + e.getMessage());
}
}
@Override
protected void weakRecover(Exception e) throws Exception {
String continueFromPage = pf.get(PageWorkerBase.CONTINUE_FROM_PAGE);
if (!StringTools.isEmpty(continueFromPage)) {
throw new ImmediateAbortException("Unable to retry with " + PageWorkerBase.CONTINUE_FROM_PAGE + "=" + continueFromPage);
}
}
}.execute();
String note = (success ? "Success: " : "Timeout: ") + pf.get(objectNameKey);
WebUtils.demoBreakPoint(scenario(), null, note);
return success;
}
private static void stopAtNextPageBegin(LinkedHashMap pf, Queue team) {
String stopAtNextPageBegin = pf.get(PageWorkerBase.STOP_AT_NEXT_PAGE_BEGIN);
if (!StringTools.isEmpty(stopAtNextPageBegin)) {
String nextPage = null;
for (PageWorkerBase worker : team) {
if (null != nextPage) {
nextPage = worker.getPageName();
break;
}
if (stopAtNextPageBegin.equals(worker.getPageName()) || stopAtNextPageBegin.equals(worker.getShortPageName())) {
nextPage = "";
}
}
if (!StringTools.isEmpty(nextPage)) {
pf.put(PageWorkerBase.STOP_AT_PAGE_BEGIN, nextPage);
}
}
}
private void teamworkInQueue(Queue workersInQueue)
throws StopAtPageBeginException, StopAtPageException {
PageWorkerBase firstWorker = workersInQueue.peek();
boolean kickoffSuccess = new Retry("teamworkInQueue.kickoff>" + StringTools.shortName(this.getClass())) {
@Override
protected void tryOnce() throws Exception {
kickOff();
}
@Override
protected void weakRecover(Exception e) throws Exception {
immediateRecover();
}
@Override
protected boolean until() throws Exception {
return firstWorker.accept();
}
@Override
protected boolean untilRecover(Exception e) throws Exception {
return firstWorker.acceptRecover(e);
}
}.execute();
if (kickoffSuccess) {
scenarioLogger.highlight("Kickoff success.");
} else {
scenarioLogger.error("Kickoff fail.");
throw new RuntimeException("Unable to kickOff");
}
while (null != workersInQueue.peek()) {
PageWorkerBase worker = workersInQueue.poll();
worker.tryStopAtPageBegin();
boolean workSuccess = new Retry("teamworkInQueue.work>" + StringTools.shortName(this.getClass()) + ">" + worker.getShortPageName()) {
@Override
protected void tryOnce() throws Exception {
worker.work();
}
@Override
protected void weakRecover(Exception e) throws Exception {
immediateRecover();
}
}.execute();
if (workSuccess) {
scenarioLogger.highlight("Work success: " + worker.toString());
} else {
scenarioLogger.error("Work fail:" + worker.toString());
throw new RuntimeException("Unable to work: " + worker.toString());
}
Map> workerOutCome = worker.getOutcome();
if (null != workerOutCome) {
outcome.putAll(workerOutCome);
}
worker.tryStopAtPage();
boolean handOffSuccess = true;
PageWorkerBase nextWorker = workersInQueue.peek();
String phrase = " [" + worker.getShortPageName() + "] ==> [" + (null == nextWorker ? "" : nextWorker.getShortPageName()) + "]";
if (null != nextWorker) {
handOffSuccess = new Retry("Retry hand off and accept " + phrase, 2 * 60 * 1000, 1000, 1000) {
@Override
protected void tryOnce() throws Exception {
worker.handOff();
}
@Override
protected void weakRecover(Exception e) throws Exception {
immediateRecover();
worker.handOffRecover(e);
}
@Override
protected boolean until() throws Exception {
return nextWorker.accept();
}
@Override
protected boolean untilRecover(Exception e) throws Exception {
//immediateRecover();
return nextWorker.acceptRecover(e);
}
}.execute();
}
if (handOffSuccess) {
scenarioLogger.highlight("Hand off and accept success:" + phrase);
} else {
scenarioLogger.error("Hand off or accept fail:" + phrase);
throw new RuntimeException("Unable to hand off or accept:" + phrase);
}
}
boolean endSuccess = new Retry("teamworkInQueue.end>" + StringTools.shortName(this.getClass())) {
@Override
protected void tryOnce() throws Exception {
end();
}
@Override
protected void weakRecover(Exception e) throws Exception {
immediateRecover();
}
}.execute();
if (endSuccess) {
scenarioLogger.highlight("End success.");
} else {
scenarioLogger.error("End fail.");
throw new RuntimeException("Unable to end");
}
}
protected void end() {
// do nothing by default
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy