| package org.apache.continuum.web.test.listener; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import com.thoughtworks.selenium.Selenium; |
| import org.apache.commons.io.FileUtils; |
| import org.apache.continuum.web.test.parent.AbstractSeleniumTest; |
| import org.testng.ITestResult; |
| import org.testng.TestListenerAdapter; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| import java.util.regex.Pattern; |
| |
| public class CaptureScreenShotsListener |
| extends TestListenerAdapter |
| { |
| @Override |
| public void onTestStart( ITestResult tr ) |
| { |
| System.out.print( "Test " + tr.getName() + "... " ); |
| super.onTestStart( tr ); |
| } |
| |
| @Override |
| public void onTestSkipped( ITestResult tr ) |
| { |
| System.out.println( "Skipped" ); |
| super.onTestSkipped( tr ); |
| } |
| |
| @Override |
| public void onTestFailure( ITestResult tr ) |
| { |
| captureError( tr ); |
| System.out.println( "Failed" ); |
| super.onTestFailure( tr ); |
| } |
| |
| @Override |
| public void onTestSuccess( ITestResult tr ) |
| { |
| System.out.println( "Success" ); |
| super.onTestFailure( tr ); |
| } |
| |
| private void captureError( ITestResult tr ) |
| { |
| captureScreenshotAndSource( tr.getTestClass().getName(), tr.getThrowable() ); |
| } |
| |
| public static void captureScreenshotAndSource( String cName, Throwable throwable ) |
| { |
| Selenium selenium = AbstractSeleniumTest.getSelenium(); |
| if ( selenium == null ) |
| { |
| // avoid swallowing exception |
| System.err.println( "Not capturing screenshot as Selenium is not initialised" ); |
| return; |
| } |
| |
| String locator = "link=Show/hide Stack Trace"; |
| if ( selenium.isElementPresent( locator ) ) |
| { |
| selenium.click( locator ); |
| } |
| |
| SimpleDateFormat sdf = new SimpleDateFormat( "yyyy.MM.dd-HH_mm_ss" ); |
| String time = sdf.format( new Date() ); |
| File targetPath = new File( "target", "screenshots" ); |
| StackTraceElement trace = getStackTraceOfCallingClass( cName, throwable.getStackTrace() ); |
| String methodName; |
| int lNumber; |
| if ( trace == null ) |
| { |
| System.err.println( "Unable to determine the calling method from class " + cName ); |
| throwable.printStackTrace(); |
| methodName = "unknown"; |
| lNumber = 0; |
| } |
| else |
| { |
| methodName = trace.getMethodName(); |
| lNumber = trace.getLineNumber(); |
| } |
| String lineNumber = Integer.toString( lNumber ); |
| String className = cName.substring( cName.lastIndexOf( '.' ) + 1 ); |
| if ( !targetPath.exists() && !targetPath.mkdirs() ) |
| { |
| System.out.println( "Unable to create screenshots directory" ); |
| return; |
| } |
| String fileBaseName = methodName + "_" + className + ".java_" + lineNumber + "-" + time; |
| |
| System.out.println( "Capturing screenshot at " + fileBaseName + ".png" ); |
| |
| try |
| { |
| selenium.windowMaximize(); |
| File fileName = getFileName( targetPath, fileBaseName, ".png" ); |
| selenium.captureEntirePageScreenshot( fileName.getAbsolutePath(), "" ); |
| } |
| catch ( RuntimeException e ) |
| { |
| System.out.println( "Error when take screenshot of error: " + e.getMessage() ); |
| } |
| try |
| { |
| File fileName = getFileName( targetPath, fileBaseName, ".html" ); |
| FileUtils.writeStringToFile( fileName, selenium.getHtmlSource() ); |
| } |
| catch ( IOException ioe ) |
| { |
| System.out.println( "Error writing HTML of error: " + ioe.getMessage() ); |
| } |
| } |
| |
| private static File getFileName( File targetPath, String fileBaseName, String ext ) |
| { |
| File fileName = new File( targetPath, fileBaseName + ext ); |
| int count = 0; |
| while ( fileName.exists() ) |
| { |
| count++; |
| fileName = new File( targetPath, fileBaseName + "_" + count + ext ); |
| } |
| return fileName; |
| } |
| |
| private static StackTraceElement getStackTraceOfCallingClass( String nameOfClass, StackTraceElement stackTrace[] ) |
| { |
| StackTraceElement lastMatch = null; |
| for ( StackTraceElement el : stackTrace ) |
| { |
| String className = el.getClassName(); |
| if ( Pattern.matches( nameOfClass, className ) ) |
| { |
| lastMatch = el; |
| } |
| } |
| return lastMatch; |
| } |
| } |