org.sitoolkit.tester.domain.test.OperationLog Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sit-wt Show documentation
Show all versions of sit-wt Show documentation
SIToolkit for Web Testing
The newest version!
/*
* Copyright 2013 Monocrea Inc.
*
* Licensed 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.
*/
package org.sitoolkit.tester.domain.test;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.sitoolkit.core.infra.util.SitFileUtils;
import org.sitoolkit.tester.infra.SitPathUtils;
import org.sitoolkit.tester.infra.TestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
/**
* このクラスは、テストの操作ログを表すリポジトリです。
* 操作ログは、カレントディレクトリ以下に以下の階層で出力します。
*
* +- opelog_yyyyMMddhhmmss
* +- img
* +- case_nnn_mmm_itemName.png
* +- case_nnn.html
*
*
* @author yuichi.kuwahara
*/
@Component
public class OperationLog {
@Resource
TestContext current;
private static final Logger LOG = LoggerFactory.getLogger(OperationLog.class);
private List records = new ArrayList();
/**
* 操作ログのVelocityテンプレート
*/
private String templatePath = "/opelog/opelog-template.vm";
/**
* 操作ログの表示に関連する資源
*/
private String[] opelogResources = new String[] {
"classpath:opelog/style.css",
"classpath:opelog/jquery.js",
"classpath:opelog/numbering.js"
};
/**
* 操作ログの出力先ディレクトリ
*/
private File opelogRootDir;
/**
* スクリーンショットの出力先ディレクトリ
*/
private File imgDir;
private String logFilePath = "target/sit-wt.log";
private List positionList = new ArrayList();
private Template tmpl;
@PostConstruct
public void init() {
opelogRootDir = new File("target", "opelog_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
opelogRootDir.mkdirs();
if (opelogRootDir.exists()) {
LOG.info("操作ログ出力ディレクトリを作成しました。{}", opelogRootDir.getAbsolutePath());
} else {
throw new TestException("操作ログ出力ディレクトリの作成に失敗しました"
+ opelogRootDir.getAbsoluteFile());
}
imgDir = new File(opelogRootDir, "img");
imgDir.mkdirs();
if (!imgDir.exists()) {
throw new TestException("スクリーンショット出力ディレクトリの作成に失敗しました"
+ imgDir.getAbsoluteFile());
}
try {
Properties prop = SitFileUtils.resource2prop(getClass(), "/velocity.properties");
Velocity.init(prop);
tmpl = Velocity.getTemplate(templatePath);
for (String opelogRes : getOpelogResources()) {
URL url = ResourceUtils.getURL(opelogRes);
File dstFile = new File(opelogRootDir, StringUtils.substringAfterLast(url.getPath(), "/"));
FileUtils.copyURLToFile(url, dstFile);
}
} catch (IOException e) {
throw new TestException(e);
}
}
/**
* 定型メッセージで操作ログを出力します。
* @param log ロガー
* @param verb ログメッセージの動作を表す単語
* @param pos
*/
public void info(Logger log, String verb, ElementPosition pos) {
info(log, pos, "{}({})を{}します",
current.getTestStep().getItemName(),
current.getTestStep().getLocator(),
verb);
}
/**
* 定型メッセージで操作ログを出力します。
* @param log ロガー
* @param object ログメッセージの目的語
* @param verb ログメッセージの動作を表す単語
* @param pos
*/
public void info(Logger log, String object, String verb, ElementPosition pos) {
info(log, pos, "{}({})に[{}]を{}します",
current.getTestStep().getItemName(),
current.getTestStep().getLocator(),
object,
verb);
}
public void info(Logger log, ElementPosition pos, String messagePattern, Object... params) {
String msg = MessageFormatter.arrayFormat(messagePattern, params).getMessage();
outLogAndAddRecord(log, msg, pos, LogLevelVo.INFO);
}
public void warn(Logger log, String messagePattern, Object... params) {
String msg = MessageFormatter.arrayFormat(messagePattern, params).getMessage();
outLogAndAddRecord(log, msg, null, LogLevelVo.WARN);
}
void outLogAndAddRecord(Logger log, String msg, ElementPosition pos, LogLevelVo logLevel) {
LogRecord record = new LogRecord();
switch (logLevel) {
case DEBUG:
log.debug(msg);
break;
case INFO:
log.info(msg);
break;
case WARN:
log.warn(msg);
break;
case ERROR:
log.error(msg);
break;
default:
// NOP
}
record.setLogLevel(logLevel);
record.setNo(current.getTestStep().getNo());
record.setLog(msg);
records.add(record);
addPosition(pos);
}
public void addPosition(ElementPosition pos) {
if (pos != null && pos != ElementPosition.EMPTY) {
pos.setNo(current.getTestStep().getNo());
positionList.add(pos);
}
}
/**
* 操作ログにスクリーンショットを追加します。
* @param file スクリーンショットの画像ファイル
* @see #addScreenshot(java.io.File, java.lang.String, boolean)
*/
public void addScreenshot(File file) {
addScreenshot(file, "");
}
/**
* 操作ログにスクリーンショットを追加します。
* @param file スクリーンショットの画像ファイル
* @param timing スクリーンショット取得タイミング ファイル名に使用する。
* @see #addScreenshot(java.io.File, java.lang.String, boolean)
*/
public void addScreenshot(File file, String timing) {
addScreenshot(file, timing, true);
}
/**
* 操作ログにスクリーンショットを追加します。
* @param file スクリーンショットの画像ファイル
* @param timing スクリーンショット取得タイミング ファイル名に使用する。
* @param withPos 操作ログを表示した際に、要素位置を表示する場合にtrueを指定
*/
public void addScreenshot(File file, String timing, boolean withPos) {
if (file == null) {
renewPositionList();
return;
}
File dstFile = new File(imgDir,
screenshotFileName(
current.getScriptName(),
current.getCaseNo(),
current.getTestStepNo(),
current.getItemName(),
timing));
try {
if (dstFile.exists()) {
dstFile = new File(imgDir, dstFile.getName() + "_" + System.currentTimeMillis());
}
FileUtils.moveFile(file, dstFile);
LogRecord record = new LogRecord();
record.setFilePath(SitPathUtils.relatvePath(opelogRootDir, dstFile));
record.setLog(dstFile.getName());
if (withPos) {
record.setPositions(positionList);
}
records.add(record);
LOG.info("スクリーンショットを取得しました {}", dstFile.getAbsolutePath());
} catch (IOException e) {
LOG.warn("スクリーンショットファイルの移動に失敗しました", e);
}
}
String screenshotFileName(String scriptName, String caseNo,
String testStepNo, String itemName, String timing) {
return StringUtils.join(
new String[] {
scriptName,
caseNo,
testStepNo,
itemName,
timing
}, "_") + ".png";
}
String opelogFileName(String scriptName, String caseNo) {
String resultHtml = ".html";
if (hasError()) {
resultHtml = "_NG.html";
}
return StringUtils.join(
new String[] {
scriptName,
caseNo
}, "_") + resultHtml;
}
/**
* 位置情報のリストを再作成します。
*/
public void renewPositionList() {
positionList = new ArrayList();
}
public void flush() {
File htmlFile = new File(
opelogRootDir,
opelogFileName(current.getScriptName(), current.getCaseNo()));
if (htmlFile.exists()) {
htmlFile = new File(htmlFile.getParent(),
System.currentTimeMillis() + "_" + htmlFile.getName());
}
LOG.info("操作ログを出力します {}", htmlFile.getAbsolutePath());
try {
String evidence = build(current.getCaseNo());
FileUtils.write(htmlFile, evidence, "UTF-8");
} catch (Exception e) {
throw new TestException("操作ログの出力に失敗しました", e);
} finally {
records.clear();
renewPositionList();
}
}
public void moveLogFile() {
try {
File logFile = new File(getLogFilePath());
FileUtils.copyFileToDirectory(logFile, opelogRootDir, true);
logFile.deleteOnExit();
} catch (IOException e) {
throw new TestException(e);
}
}
/**
* 操作ログファイルに出力する文字列を構築します。
*
* @return 操作ログファイルに出力する文字列
*/
String build(String caseNo) {
VelocityContext context = new VelocityContext();
StringWriter writer = new StringWriter();
context.put("opeLog", this);
context.put("caseNo", caseNo);
context.put("testScriptName", current.getScriptName());
context.put("result", (hasError()) ? "NG" : "");
tmpl.merge(context, writer);
return writer.toString();
}
public List getRecords() {
return Collections.unmodifiableList(records);
}
/**
* エラーログを出力します。
*/
void error(Logger log, String msg) {
LogRecord record = new LogRecord();
log.error(msg);
record.setNo(current.getTestStepNo());
record.setLog(msg);
record.setLogLevel(LogLevelVo.ERROR);
records.add(record);
}
boolean hasError() {
for (LogRecord logRecord : records) {
if (LogLevelVo.ERROR.equals(logRecord.getLogLevel())) {
return true;
}
}
return false;
}
public String getLogFilePath() {
return logFilePath;
}
public void setLogFilePath(String logFilePath) {
this.logFilePath = logFilePath;
}
public String getTemplatePath() {
return templatePath;
}
public void setTemplatePath(String templatePath) {
this.templatePath = templatePath;
}
public String[] getOpelogResources() {
return opelogResources;
}
public void setOpelogResources(String[] opelogResources) {
this.opelogResources = opelogResources;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy