Last active
August 29, 2015 13:56
-
-
Save jclarkin/5fe969ce98d4890c89dc to your computer and use it in GitHub Desktop.
Selenium (Java) Video recorder for JUnit4. Just add a @rule to your JUnit class and specify on which states to record (Pass, Fail, Error).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.Assert; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import org.junit.runners.JUnit4; | |
import ScreenRecorderRule; | |
/** | |
* This is a sample test class that will output videos of Selenium WebDriver execution on Fail and | |
* Error results. | |
*/ | |
@RunWith( JUnit4.class ) | |
public class CreateAdHocTaskExample | |
{ | |
@Rule public ScreenRecorderRule iRule = new ScreenRecorderRule( false, true, true ); | |
/** | |
* This is a sample test case | |
*/ | |
@Test public void testCreateAdHocTask() | |
{ | |
Assert.fail( "Not yet implemented" ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.rules.TestRule; | |
import org.junit.runner.Description; | |
import org.junit.runners.model.Statement; | |
/** | |
* JUnit Rule to record the test execution to an AVI file, depending on the test result status | |
* (success, fail, or error) | |
* | |
* @author jclarkin | |
*/ | |
public class ScreenRecorderRule | |
implements TestRule | |
{ | |
private final boolean iRecordError; | |
private final boolean iRecordFailure; | |
private final boolean iRecordSuccess; | |
/** | |
* Creates a new {@linkplain ScreenRecorderRule} object. | |
* | |
* @param aRecordSuccess If true, will record test on success | |
* @param aRecordFailure If true, will record test on failure | |
* @param aRecordError If true, will record test on error | |
*/ | |
public ScreenRecorderRule( boolean aRecordSuccess, boolean aRecordFailure, | |
boolean aRecordError | |
) | |
{ | |
super(); | |
this.iRecordSuccess = aRecordSuccess; | |
this.iRecordFailure = aRecordFailure; | |
this.iRecordError = aRecordError; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override public Statement apply( Statement aBase, Description aDescription ) | |
{ | |
String lFilename = aDescription.getClassName() + "." + aDescription.getMethodName(); | |
return new ScreenRecorderStatement( | |
aBase, | |
lFilename, | |
iRecordSuccess, | |
iRecordFailure, | |
iRecordError | |
); | |
} | |
/** | |
* Handles execution of test and potentially records the execution as well | |
*/ | |
public class ScreenRecorderStatement | |
extends Statement | |
{ | |
private final Statement iBase; | |
private final String iFilename; | |
private final boolean iRecordError; | |
private final boolean iRecordFailure; | |
private final boolean iRecordSuccess; | |
/** | |
* Creates a new {@linkplain ScreenRecorderStatement} object. | |
* | |
* @param aBase The base test statement | |
* @param aFilename The prefix to use for the recording file name | |
* @param aRecordSuccess If true, will record test on success | |
* @param aRecordFailure If true, will record test on failure | |
* @param aRecordError If true, will record test on error | |
*/ | |
public ScreenRecorderStatement( | |
Statement aBase, | |
String aFilename, | |
boolean aRecordSuccess, | |
boolean aRecordFailure, | |
boolean aRecordError | |
) | |
{ | |
this.iRecordSuccess = aRecordSuccess; | |
this.iRecordFailure = aRecordFailure; | |
this.iRecordError = aRecordError; | |
this.iBase = aBase; | |
this.iFilename = aFilename; | |
} | |
/** | |
* Executes the test and saves a recording depending on the test result status | |
* | |
* @throws Throwable If an error or failure occurs | |
*/ | |
@Override public void evaluate() | |
throws Throwable | |
{ | |
TestRecorder lRecorder = new TestRecorder( iFilename ); | |
boolean lSucceeded = false; | |
boolean lFailed = false; | |
boolean lError = false; | |
try { | |
lRecorder.start(); | |
iBase.evaluate(); | |
lSucceeded = true; | |
} catch ( Throwable e ) { | |
if ( e instanceof AssertionError ) { | |
lFailed = true; | |
} else { | |
lError = true; | |
} | |
throw e; | |
} finally { | |
lRecorder.stop(); | |
boolean lKeepFile = | |
( lSucceeded && iRecordSuccess ) || ( lFailed && iRecordFailure ) || | |
( lError && iRecordError ); | |
// If not keeping the file, delete it | |
if ( !lKeepFile ) { | |
lRecorder.delete(); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.IOException; | |
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
import org.monte.media.Format; | |
import org.monte.media.FormatKeys.MediaType; | |
import org.monte.media.Registry; | |
import static org.monte.media.VideoFormatKeys.*; | |
import org.monte.media.math.Rational; | |
import org.monte.screenrecorder.ScreenRecorder; | |
import java.awt.AWTException; | |
import java.awt.GraphicsConfiguration; | |
import java.awt.GraphicsEnvironment; | |
/** | |
* A customized instance of the ScreenRecorder that allows the filename prefix to be specified, as | |
* well as functionality to delete the recording | |
*/ | |
public class TestRecorder | |
extends ScreenRecorder | |
{ | |
private String iFilename; | |
private File iMovieFile; | |
/** | |
* Creates a new {@linkplain TestRecorder} object. | |
* | |
* @param aFilename The Prefix filename to use | |
* | |
* @throws IOException If an error occurs with saving the recording | |
* @throws AWTException If an error occurs in accessing the video screen | |
*/ | |
public TestRecorder( String aFilename ) | |
throws IOException, AWTException | |
{ | |
super( buildConfig(), buildFileFormat(), buildScreenFormat(), buildMouseFormat(), null ); | |
iFilename = aFilename; | |
} | |
/** | |
* Delete the recorded file | |
* | |
* @return True if succeeded to delete | |
*/ | |
public boolean delete() | |
{ | |
boolean lDeleted = false; | |
if ( State.DONE == this.getState() ) { | |
lDeleted = iMovieFile.delete(); | |
} | |
return lDeleted; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override protected File createMovieFile( Format aFileFormat ) | |
throws IOException | |
{ | |
if ( !movieFolder.exists() ) { | |
movieFolder.mkdirs(); | |
} else if ( !movieFolder.isDirectory() ) { | |
throw new IOException( "\"" + movieFolder + "\" is not a directory." ); | |
} | |
SimpleDateFormat lDateFormat = new SimpleDateFormat( "yyyy-MM-dd 'at' HH.mm.ss" ); | |
iMovieFile = | |
new File( | |
movieFolder, // | |
iFilename + " " + lDateFormat.format( new Date() ) + "." + | |
Registry.getInstance().getExtension( aFileFormat ) | |
); | |
return iMovieFile; | |
} | |
/** | |
* Generate the Graphics configuration used to access the video screen | |
* | |
* @return Graphics configuration | |
*/ | |
private static GraphicsConfiguration buildConfig() | |
{ | |
return GraphicsEnvironment.getLocalGraphicsEnvironment() | |
.getDefaultScreenDevice() | |
.getDefaultConfiguration(); | |
} | |
/** | |
* Generate the fileformat for the recording to be saved | |
* | |
* @return The fileformat of the recording | |
*/ | |
private static Format buildFileFormat() | |
{ | |
return new Format( MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI ); | |
} | |
/** | |
* Generate the Mouse accessor details for recording | |
* | |
* @return Mouse accessor configuration | |
*/ | |
private static Format buildMouseFormat() | |
{ | |
return new Format( | |
MediaTypeKey, | |
MediaType.VIDEO, | |
EncodingKey, | |
"black", | |
FrameRateKey, | |
Rational.valueOf( 30 ) | |
); | |
} | |
/** | |
* Generate the Screen accessor details for recording | |
* | |
* @return Screen accessor configuration | |
*/ | |
private static Format buildScreenFormat() | |
{ | |
return new Format( | |
MediaTypeKey, | |
MediaType.VIDEO, | |
EncodingKey, | |
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, | |
CompressorNameKey, | |
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, | |
DepthKey, | |
24, | |
FrameRateKey, | |
Rational.valueOf( 15 ), | |
QualityKey, | |
1.0f, | |
KeyFrameIntervalKey, | |
15 * 60 | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment