package me.alb_i986.selenium.tinafw.tests;

import me.alb_i986.selenium.tinafw.tests.rules.BrowserManager;
import me.alb_i986.selenium.tinafw.tests.rules.HtmlReporter;
import me.alb_i986.selenium.tinafw.tests.rules.TestRetrier;
import me.alb_i986.selenium.tinafw.utils.PropertyLoader;

import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

/**
 * JunitWebTest provides a few useful JUnit Rules out of the box:
 * <ul>
 * <li>{@link TestRetrier}: retries a failing test</li>
 * <li>{@link BrowserManager}: closes the browsers when a test finishes</li>
 * <li>{@link TestWatcher}: logs the state of the running test (e.g.: "passed", "failed")</li>
 * </ul>
 * <p>
 * In order for the BrowserManager to do its job, each test must
 * register every Browser it opens to the BrowserManager. E.g.:
 * <pre>
 * {@code
 * public void before() {
 * 	super.before();
 * 	user = new User();
 * 	browserManager.registerBrowsers(user.getBrowser());
 * }
 * }
 * </pre>
 */
public abstract class JunitWebTest implements WebTest {
	
	public static final int MAX_EXECUTIONS =
			Integer.parseInt(PropertyLoader.getTinaFwConfig("max_executions"));
	
	protected static final Logger logger = Logger.getLogger(WebTest.class);
	
    @Rule
    public TestRetrier retryRule = new TestRetrier(MAX_EXECUTIONS);

	@Rule
	public BrowserManager browserManager = new BrowserManager();

	@Rule
	public HtmlReporter htmlReporter = new HtmlReporter();
		
	@Rule
	public TestWatcher watchman = new TestWatcher() {
		
		@Override
		protected void skipped(AssumptionViolatedException e, Description description) {
			super.skipped(e, description);
			logger.error("END test: SKIPPED > " + description.getDisplayName() + " -- cause: " + e);
		}

		@Override
		protected void starting(Description description) {
			super.starting(description);
			logger.info("BEGIN test " + description.getDisplayName());
		}

		@Override
		protected void failed(Throwable e, Description description) {
			super.failed(e, description);
			logger.error("END test: FAILED > " + description.getDisplayName());
		}

		@Override
		protected void succeeded(Description description) {
			super.succeeded(description);
			logger.info("END test: PASSED > " + description.getDisplayName());
		}
	};

	/**
	 * Empty after method.
	 */
	@After
	public void after() {
	}

	/**
	 * Empty before method.
	 */
	@Before
	public void before() {
	}
	
}

@@ -438,16 +438,83 @@
 eption;%0A
+import org.junit.rules.RuleChain;%0Aimport org.junit.rules.TestRule;%0A
 import o
@@ -537,24 +537,24 @@
 estWatcher;%0A
-
 import org.j
@@ -759,36 +759,129 @@
 the 
-browsers when a test finishe
+registered browsers as soon as a test finishes%3C/li%3E%0A * %3Cli%3E%7B@link HtmlReporter%7D: generated an HTML report with screenshot
 s%3C/l
@@ -1521,16 +1521,21 @@
 tLogger(
+Junit
 WebTest.
@@ -1546,30 +1546,26 @@
 s);%0A
-%09%0A
     
-@Rule
 %0A    p
-ublic
+rotected
  Tes
@@ -1618,31 +1618,29 @@
 TIONS);%0A
-%0A%09@Rule%0A%09public
+    protected
  Browser
@@ -1686,31 +1686,29 @@
 ager();%0A
-%0A%09@Rule%0A%09public
+    protected
  HtmlRep
@@ -1753,24 +1753,17 @@
 );%0A%09
-%09%0A%09@Rule%0A%09public
+protected
  Tes
@@ -2558,16 +2558,168 @@
 %09%7D%0A%09%7D;%0A%0A
+%09@Rule%0A%09public TestRule ruleChain =%0A%09%09RuleChain%0A%09%09%09.outerRule(watchman)%0A%09%09%09.around(browserManager)%0A%09%09%09.around(htmlReporter)%0A%09%09%09.around(retryRule)%0A%09%09;%0A%09%0A
 %09/**%0A%09 *

add RuleChain